mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
incorrect case diagnostics for type aliases
This commit is contained in:
parent
0ffc088439
commit
080d223dd4
3 changed files with 76 additions and 15 deletions
|
@ -20,7 +20,7 @@ use hir_def::{
|
||||||
hir::{Pat, PatId},
|
hir::{Pat, PatId},
|
||||||
src::HasSource,
|
src::HasSource,
|
||||||
AdtId, AttrDefId, ConstId, EnumId, FunctionId, ItemContainerId, Lookup, ModuleDefId, ModuleId,
|
AdtId, AttrDefId, ConstId, EnumId, FunctionId, ItemContainerId, Lookup, ModuleDefId, ModuleId,
|
||||||
StaticId, StructId, TraitId,
|
StaticId, StructId, TraitId, TypeAliasId,
|
||||||
};
|
};
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
name::{AsName, Name},
|
name::{AsName, Name},
|
||||||
|
@ -84,6 +84,7 @@ pub enum IdentType {
|
||||||
StaticVariable,
|
StaticVariable,
|
||||||
Structure,
|
Structure,
|
||||||
Trait,
|
Trait,
|
||||||
|
TypeAlias,
|
||||||
Variable,
|
Variable,
|
||||||
Variant,
|
Variant,
|
||||||
}
|
}
|
||||||
|
@ -100,6 +101,7 @@ impl fmt::Display for IdentType {
|
||||||
IdentType::StaticVariable => "Static variable",
|
IdentType::StaticVariable => "Static variable",
|
||||||
IdentType::Structure => "Structure",
|
IdentType::Structure => "Structure",
|
||||||
IdentType::Trait => "Trait",
|
IdentType::Trait => "Trait",
|
||||||
|
IdentType::TypeAlias => "Type alias",
|
||||||
IdentType::Variable => "Variable",
|
IdentType::Variable => "Variable",
|
||||||
IdentType::Variant => "Variant",
|
IdentType::Variant => "Variant",
|
||||||
};
|
};
|
||||||
|
@ -143,6 +145,7 @@ impl<'a> DeclValidator<'a> {
|
||||||
ModuleDefId::AdtId(adt) => self.validate_adt(adt),
|
ModuleDefId::AdtId(adt) => self.validate_adt(adt),
|
||||||
ModuleDefId::ConstId(const_id) => self.validate_const(const_id),
|
ModuleDefId::ConstId(const_id) => self.validate_const(const_id),
|
||||||
ModuleDefId::StaticId(static_id) => self.validate_static(static_id),
|
ModuleDefId::StaticId(static_id) => self.validate_static(static_id),
|
||||||
|
ModuleDefId::TypeAliasId(type_alias_id) => self.validate_type_alias(type_alias_id),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -845,6 +848,54 @@ impl<'a> DeclValidator<'a> {
|
||||||
self.sink.push(diagnostic);
|
self.sink.push(diagnostic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validate_type_alias(&mut self, type_alias_id: TypeAliasId) {
|
||||||
|
let container = type_alias_id.lookup(self.db.upcast()).container;
|
||||||
|
if self.is_trait_impl_container(container) {
|
||||||
|
cov_mark::hit!(trait_impl_assoc_type_incorrect_case_ignored);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether non-snake case identifiers are allowed for this type alias.
|
||||||
|
if self.allowed(type_alias_id.into(), allow::NON_CAMEL_CASE_TYPES, false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the type alias name.
|
||||||
|
let data = self.db.type_alias_data(type_alias_id);
|
||||||
|
let type_alias_name = data.name.display(self.db.upcast()).to_string();
|
||||||
|
let type_alias_name_replacement =
|
||||||
|
to_camel_case(&type_alias_name).map(|new_name| Replacement {
|
||||||
|
current_name: data.name.clone(),
|
||||||
|
suggested_text: new_name,
|
||||||
|
expected_case: CaseType::UpperCamelCase,
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(replacement) = type_alias_name_replacement {
|
||||||
|
let type_alias_loc = type_alias_id.lookup(self.db.upcast());
|
||||||
|
let type_alias_src = type_alias_loc.source(self.db.upcast());
|
||||||
|
|
||||||
|
let Some(ast_ptr) = type_alias_src.value.name() else {
|
||||||
|
never!(
|
||||||
|
"Replacement ({:?}) was generated for a type alias without a name: {:?}",
|
||||||
|
replacement,
|
||||||
|
type_alias_src
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let diagnostic = IncorrectCase {
|
||||||
|
file: type_alias_src.file_id,
|
||||||
|
ident_type: IdentType::TypeAlias,
|
||||||
|
ident: AstPtr::new(&ast_ptr),
|
||||||
|
expected_case: replacement.expected_case,
|
||||||
|
ident_text: type_alias_name,
|
||||||
|
suggested_text: replacement.suggested_text,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.sink.push(diagnostic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn is_trait_impl_container(&self, container_id: ItemContainerId) -> bool {
|
fn is_trait_impl_container(&self, container_id: ItemContainerId) -> bool {
|
||||||
if let ItemContainerId::ImplId(impl_id) = container_id {
|
if let ItemContainerId::ImplId(impl_id) = container_id {
|
||||||
if self.db.impl_trait(impl_id).is_some() {
|
if self.db.impl_trait(impl_id).is_some() {
|
||||||
|
|
|
@ -565,13 +565,7 @@ impl Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
for item in t.items(db) {
|
for item in t.items(db) {
|
||||||
let def: DefWithBody = match item {
|
item.diagnostics(db, acc);
|
||||||
AssocItem::Function(it) => it.into(),
|
|
||||||
AssocItem::Const(it) => it.into(),
|
|
||||||
AssocItem::TypeAlias(_) => continue,
|
|
||||||
};
|
|
||||||
|
|
||||||
def.diagnostics(db, acc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
acc.extend(def.diagnostics(db))
|
acc.extend(def.diagnostics(db))
|
||||||
|
@ -741,13 +735,7 @@ impl Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
for &item in &db.impl_data(impl_def.id).items {
|
for &item in &db.impl_data(impl_def.id).items {
|
||||||
let def: DefWithBody = match AssocItem::from(item) {
|
AssocItem::from(item).diagnostics(db, acc);
|
||||||
AssocItem::Function(it) => it.into(),
|
|
||||||
AssocItem::Const(it) => it.into(),
|
|
||||||
AssocItem::TypeAlias(_) => continue,
|
|
||||||
};
|
|
||||||
|
|
||||||
def.diagnostics(db, acc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2662,6 +2650,22 @@ impl AssocItem {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn diagnostics(self, db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>) {
|
||||||
|
match self {
|
||||||
|
AssocItem::Function(func) => {
|
||||||
|
DefWithBody::from(func).diagnostics(db, acc);
|
||||||
|
}
|
||||||
|
AssocItem::Const(const_) => {
|
||||||
|
DefWithBody::from(const_).diagnostics(db, acc);
|
||||||
|
}
|
||||||
|
AssocItem::TypeAlias(type_alias) => {
|
||||||
|
for diag in hir_ty::diagnostics::incorrect_case(db, type_alias.id.into()) {
|
||||||
|
acc.push(diag.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasVisibility for AssocItem {
|
impl HasVisibility for AssocItem {
|
||||||
|
|
|
@ -470,6 +470,8 @@ trait BAD_TRAIT {
|
||||||
// ^^^^^^^^^ 💡 warn: Trait `BAD_TRAIT` should have CamelCase name, e.g. `BadTrait`
|
// ^^^^^^^^^ 💡 warn: Trait `BAD_TRAIT` should have CamelCase name, e.g. `BadTrait`
|
||||||
const bad_const: u8;
|
const bad_const: u8;
|
||||||
// ^^^^^^^^^ 💡 warn: Constant `bad_const` should have UPPER_SNAKE_CASE name, e.g. `BAD_CONST`
|
// ^^^^^^^^^ 💡 warn: Constant `bad_const` should have UPPER_SNAKE_CASE name, e.g. `BAD_CONST`
|
||||||
|
type BAD_TYPE;
|
||||||
|
// ^^^^^^^^ 💡 warn: Type alias `BAD_TYPE` should have CamelCase name, e.g. `BadType`
|
||||||
fn BAD_FUNCTION();
|
fn BAD_FUNCTION();
|
||||||
// ^^^^^^^^^^^^ 💡 warn: Function `BAD_FUNCTION` should have snake_case name, e.g. `bad_function`
|
// ^^^^^^^^^^^^ 💡 warn: Function `BAD_FUNCTION` should have snake_case name, e.g. `bad_function`
|
||||||
fn BadFunction();
|
fn BadFunction();
|
||||||
|
@ -482,6 +484,7 @@ trait BAD_TRAIT {
|
||||||
#[test]
|
#[test]
|
||||||
fn no_diagnostics_for_trait_impl_assoc_items_except_pats_in_body() {
|
fn no_diagnostics_for_trait_impl_assoc_items_except_pats_in_body() {
|
||||||
cov_mark::check!(trait_impl_assoc_const_incorrect_case_ignored);
|
cov_mark::check!(trait_impl_assoc_const_incorrect_case_ignored);
|
||||||
|
cov_mark::check!(trait_impl_assoc_type_incorrect_case_ignored);
|
||||||
cov_mark::check_count!(trait_impl_assoc_func_name_incorrect_case_ignored, 2);
|
cov_mark::check_count!(trait_impl_assoc_func_name_incorrect_case_ignored, 2);
|
||||||
cov_mark::check!(trait_impl_assoc_func_param_incorrect_case_ignored);
|
cov_mark::check!(trait_impl_assoc_func_param_incorrect_case_ignored);
|
||||||
check_diagnostics_with_disabled(
|
check_diagnostics_with_disabled(
|
||||||
|
@ -490,6 +493,8 @@ trait BAD_TRAIT {
|
||||||
// ^^^^^^^^^ 💡 warn: Trait `BAD_TRAIT` should have CamelCase name, e.g. `BadTrait`
|
// ^^^^^^^^^ 💡 warn: Trait `BAD_TRAIT` should have CamelCase name, e.g. `BadTrait`
|
||||||
const bad_const: u8;
|
const bad_const: u8;
|
||||||
// ^^^^^^^^^ 💡 warn: Constant `bad_const` should have UPPER_SNAKE_CASE name, e.g. `BAD_CONST`
|
// ^^^^^^^^^ 💡 warn: Constant `bad_const` should have UPPER_SNAKE_CASE name, e.g. `BAD_CONST`
|
||||||
|
type BAD_TYPE;
|
||||||
|
// ^^^^^^^^ 💡 warn: Type alias `BAD_TYPE` should have CamelCase name, e.g. `BadType`
|
||||||
fn BAD_FUNCTION(BAD_PARAM: u8);
|
fn BAD_FUNCTION(BAD_PARAM: u8);
|
||||||
// ^^^^^^^^^^^^ 💡 warn: Function `BAD_FUNCTION` should have snake_case name, e.g. `bad_function`
|
// ^^^^^^^^^^^^ 💡 warn: Function `BAD_FUNCTION` should have snake_case name, e.g. `bad_function`
|
||||||
// ^^^^^^^^^ 💡 warn: Parameter `BAD_PARAM` should have snake_case name, e.g. `bad_param`
|
// ^^^^^^^^^ 💡 warn: Parameter `BAD_PARAM` should have snake_case name, e.g. `bad_param`
|
||||||
|
@ -499,6 +504,7 @@ trait BAD_TRAIT {
|
||||||
|
|
||||||
impl BAD_TRAIT for () {
|
impl BAD_TRAIT for () {
|
||||||
const bad_const: u8 = 1;
|
const bad_const: u8 = 1;
|
||||||
|
type BAD_TYPE = ();
|
||||||
fn BAD_FUNCTION(BAD_PARAM: u8) {
|
fn BAD_FUNCTION(BAD_PARAM: u8) {
|
||||||
let BAD_VAR = 10;
|
let BAD_VAR = 10;
|
||||||
// ^^^^^^^ 💡 warn: Variable `BAD_VAR` should have snake_case name, e.g. `bad_var`
|
// ^^^^^^^ 💡 warn: Variable `BAD_VAR` should have snake_case name, e.g. `bad_var`
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue