Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
improve non_camel_case_types diagnostics
Use a structured suggestion and tighten the span to just the identifier.
  • Loading branch information
euclio committed Jan 8, 2019
1 parent e379970 commit 1b28f5a
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 82 deletions.
33 changes: 19 additions & 14 deletions src/librustc_lint/nonstandard_style.rs
Expand Up @@ -41,13 +41,12 @@ declare_lint! {
pub struct NonCamelCaseTypes;

impl NonCamelCaseTypes {
fn check_case(&self, cx: &EarlyContext, sort: &str, name: ast::Name, span: Span) {
fn check_case(&self, cx: &EarlyContext, sort: &str, ident: &Ident) {
fn char_has_case(c: char) -> bool {
c.is_lowercase() || c.is_uppercase()
}

fn is_camel_case(name: ast::Name) -> bool {
let name = name.as_str();
fn is_camel_case(name: &str) -> bool {
let name = name.trim_matches('_');
if name.is_empty() {
return true;
Expand Down Expand Up @@ -87,14 +86,20 @@ impl NonCamelCaseTypes {
}).0
}

let name = &ident.name.as_str();

if !is_camel_case(name) {
let c = to_camel_case(&name.as_str());
let m = if c.is_empty() {
format!("{} `{}` should have a camel case name such as `CamelCase`", sort, name)
} else {
format!("{} `{}` should have a camel case name such as `{}`", sort, name, c)
};
cx.span_lint(NON_CAMEL_CASE_TYPES, span, &m);
let c = to_camel_case(name);

let msg = format!("{} `{}` should have a camel case name", sort, name);
cx.struct_span_lint(NON_CAMEL_CASE_TYPES, ident.span, &msg)
.span_suggestion_with_applicability(
ident.span,
"convert the identifier to camel case",
c,
Applicability::MaybeIncorrect,
)
.emit();
}
}
}
Expand Down Expand Up @@ -123,19 +128,19 @@ impl EarlyLintPass for NonCamelCaseTypes {
ast::ItemKind::Ty(..) |
ast::ItemKind::Enum(..) |
ast::ItemKind::Struct(..) |
ast::ItemKind::Union(..) => self.check_case(cx, "type", it.ident.name, it.span),
ast::ItemKind::Trait(..) => self.check_case(cx, "trait", it.ident.name, it.span),
ast::ItemKind::Union(..) => self.check_case(cx, "type", &it.ident),
ast::ItemKind::Trait(..) => self.check_case(cx, "trait", &it.ident),
_ => (),
}
}

fn check_variant(&mut self, cx: &EarlyContext, v: &ast::Variant, _: &ast::Generics) {
self.check_case(cx, "variant", v.node.ident.name, v.span);
self.check_case(cx, "variant", &v.node.ident);
}

fn check_generic_param(&mut self, cx: &EarlyContext, param: &ast::GenericParam) {
if let ast::GenericParamKind::Type { .. } = param.kind {
self.check_case(cx, "type parameter", param.ident.name, param.ident.span);
self.check_case(cx, "type parameter", &param.ident);
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/lint/lint-group-nonstandard-style.stderr
@@ -1,8 +1,8 @@
warning: type `snake_case` should have a camel case name such as `SnakeCase`
--> $DIR/lint-group-nonstandard-style.rs:22:9
warning: type `snake_case` should have a camel case name
--> $DIR/lint-group-nonstandard-style.rs:22:16
|
LL | struct snake_case; //~ WARN should have a camel
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^ help: convert the identifier to camel case: `SnakeCase`
|
note: lint level defined here
--> $DIR/lint-group-nonstandard-style.rs:18:17
Expand Down
22 changes: 11 additions & 11 deletions src/test/ui/lint/lint-non-camel-case-types.rs
Expand Up @@ -2,31 +2,31 @@
#![allow(dead_code)]

struct ONE_TWO_THREE;
//~^ ERROR type `ONE_TWO_THREE` should have a camel case name such as `OneTwoThree`
//~^ ERROR type `ONE_TWO_THREE` should have a camel case name

struct foo { //~ ERROR type `foo` should have a camel case name such as `Foo`
struct foo { //~ ERROR type `foo` should have a camel case name
bar: isize,
}

enum foo2 { //~ ERROR type `foo2` should have a camel case name such as `Foo2`
enum foo2 { //~ ERROR type `foo2` should have a camel case name
Bar
}

struct foo3 { //~ ERROR type `foo3` should have a camel case name such as `Foo3`
struct foo3 { //~ ERROR type `foo3` should have a camel case name
bar: isize
}

type foo4 = isize; //~ ERROR type `foo4` should have a camel case name such as `Foo4`
type foo4 = isize; //~ ERROR type `foo4` should have a camel case name

enum Foo5 {
bar //~ ERROR variant `bar` should have a camel case name such as `Bar`
bar //~ ERROR variant `bar` should have a camel case name
}

trait foo6 { //~ ERROR trait `foo6` should have a camel case name such as `Foo6`
trait foo6 { //~ ERROR trait `foo6` should have a camel case name
fn dummy(&self) { }
}

fn f<ty>(_: ty) {} //~ ERROR type parameter `ty` should have a camel case name such as `Ty`
fn f<ty>(_: ty) {} //~ ERROR type parameter `ty` should have a camel case name

#[repr(C)]
struct foo7 {
Expand All @@ -35,10 +35,10 @@ struct foo7 {

struct X86_64;

struct X86__64; //~ ERROR type `X86__64` should have a camel case name such as `X86_64`
struct X86__64; //~ ERROR type `X86__64` should have a camel case name

struct Abc_123; //~ ERROR type `Abc_123` should have a camel case name such as `Abc123`
struct Abc_123; //~ ERROR type `Abc_123` should have a camel case name

struct A1_b2_c3; //~ ERROR type `A1_b2_c3` should have a camel case name such as `A1B2C3`
struct A1_b2_c3; //~ ERROR type `A1_b2_c3` should have a camel case name

fn main() { }
90 changes: 41 additions & 49 deletions src/test/ui/lint/lint-non-camel-case-types.stderr
@@ -1,82 +1,74 @@
error: type `ONE_TWO_THREE` should have a camel case name such as `OneTwoThree`
--> $DIR/lint-non-camel-case-types.rs:4:1
error: type `ONE_TWO_THREE` should have a camel case name
--> $DIR/lint-non-camel-case-types.rs:4:8
|
LL | struct ONE_TWO_THREE;
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ help: convert the identifier to camel case: `OneTwoThree`
|
note: lint level defined here
--> $DIR/lint-non-camel-case-types.rs:1:11
|
LL | #![forbid(non_camel_case_types)]
| ^^^^^^^^^^^^^^^^^^^^

error: type `foo` should have a camel case name such as `Foo`
--> $DIR/lint-non-camel-case-types.rs:7:1
error: type `foo` should have a camel case name
--> $DIR/lint-non-camel-case-types.rs:7:8
|
LL | / struct foo { //~ ERROR type `foo` should have a camel case name such as `Foo`
LL | | bar: isize,
LL | | }
| |_^
LL | struct foo { //~ ERROR type `foo` should have a camel case name
| ^^^ help: convert the identifier to camel case: `Foo`

error: type `foo2` should have a camel case name such as `Foo2`
--> $DIR/lint-non-camel-case-types.rs:11:1
error: type `foo2` should have a camel case name
--> $DIR/lint-non-camel-case-types.rs:11:6
|
LL | / enum foo2 { //~ ERROR type `foo2` should have a camel case name such as `Foo2`
LL | | Bar
LL | | }
| |_^
LL | enum foo2 { //~ ERROR type `foo2` should have a camel case name
| ^^^^ help: convert the identifier to camel case: `Foo2`

error: type `foo3` should have a camel case name such as `Foo3`
--> $DIR/lint-non-camel-case-types.rs:15:1
error: type `foo3` should have a camel case name
--> $DIR/lint-non-camel-case-types.rs:15:8
|
LL | / struct foo3 { //~ ERROR type `foo3` should have a camel case name such as `Foo3`
LL | | bar: isize
LL | | }
| |_^
LL | struct foo3 { //~ ERROR type `foo3` should have a camel case name
| ^^^^ help: convert the identifier to camel case: `Foo3`

error: type `foo4` should have a camel case name such as `Foo4`
--> $DIR/lint-non-camel-case-types.rs:19:1
error: type `foo4` should have a camel case name
--> $DIR/lint-non-camel-case-types.rs:19:6
|
LL | type foo4 = isize; //~ ERROR type `foo4` should have a camel case name such as `Foo4`
| ^^^^^^^^^^^^^^^^^^
LL | type foo4 = isize; //~ ERROR type `foo4` should have a camel case name
| ^^^^ help: convert the identifier to camel case: `Foo4`

error: variant `bar` should have a camel case name such as `Bar`
error: variant `bar` should have a camel case name
--> $DIR/lint-non-camel-case-types.rs:22:5
|
LL | bar //~ ERROR variant `bar` should have a camel case name such as `Bar`
| ^^^
LL | bar //~ ERROR variant `bar` should have a camel case name
| ^^^ help: convert the identifier to camel case: `Bar`

error: trait `foo6` should have a camel case name such as `Foo6`
--> $DIR/lint-non-camel-case-types.rs:25:1
error: trait `foo6` should have a camel case name
--> $DIR/lint-non-camel-case-types.rs:25:7
|
LL | / trait foo6 { //~ ERROR trait `foo6` should have a camel case name such as `Foo6`
LL | | fn dummy(&self) { }
LL | | }
| |_^
LL | trait foo6 { //~ ERROR trait `foo6` should have a camel case name
| ^^^^ help: convert the identifier to camel case: `Foo6`

error: type parameter `ty` should have a camel case name such as `Ty`
error: type parameter `ty` should have a camel case name
--> $DIR/lint-non-camel-case-types.rs:29:6
|
LL | fn f<ty>(_: ty) {} //~ ERROR type parameter `ty` should have a camel case name such as `Ty`
| ^^
LL | fn f<ty>(_: ty) {} //~ ERROR type parameter `ty` should have a camel case name
| ^^ help: convert the identifier to camel case: `Ty`

error: type `X86__64` should have a camel case name such as `X86_64`
--> $DIR/lint-non-camel-case-types.rs:38:1
error: type `X86__64` should have a camel case name
--> $DIR/lint-non-camel-case-types.rs:38:8
|
LL | struct X86__64; //~ ERROR type `X86__64` should have a camel case name such as `X86_64`
| ^^^^^^^^^^^^^^^
LL | struct X86__64; //~ ERROR type `X86__64` should have a camel case name
| ^^^^^^^ help: convert the identifier to camel case: `X86_64`

error: type `Abc_123` should have a camel case name such as `Abc123`
--> $DIR/lint-non-camel-case-types.rs:40:1
error: type `Abc_123` should have a camel case name
--> $DIR/lint-non-camel-case-types.rs:40:8
|
LL | struct Abc_123; //~ ERROR type `Abc_123` should have a camel case name such as `Abc123`
| ^^^^^^^^^^^^^^^
LL | struct Abc_123; //~ ERROR type `Abc_123` should have a camel case name
| ^^^^^^^ help: convert the identifier to camel case: `Abc123`

error: type `A1_b2_c3` should have a camel case name such as `A1B2C3`
--> $DIR/lint-non-camel-case-types.rs:42:1
error: type `A1_b2_c3` should have a camel case name
--> $DIR/lint-non-camel-case-types.rs:42:8
|
LL | struct A1_b2_c3; //~ ERROR type `A1_b2_c3` should have a camel case name such as `A1B2C3`
| ^^^^^^^^^^^^^^^^
LL | struct A1_b2_c3; //~ ERROR type `A1_b2_c3` should have a camel case name
| ^^^^^^^^ help: convert the identifier to camel case: `A1B2C3`

error: aborting due to 11 previous errors

@@ -1,3 +1,5 @@
// compile-pass

#![deny(non_camel_case_types)]

pub enum Foo {
Expand Down
@@ -1,3 +1,5 @@
// compile-pass

#![allow(dead_code)]
// This is ok because we often use the trailing underscore to mean 'prime'

Expand Down
@@ -1,6 +1,6 @@
//
#![allow(dead_code)]
// compile-pass

#![allow(dead_code)]

#![forbid(non_camel_case_types)]
#![forbid(non_upper_case_globals)]
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/utf8_idents.rs
Expand Up @@ -3,7 +3,7 @@
fn foo<
'β, //~ ERROR non-ascii idents are not fully supported
γ //~ ERROR non-ascii idents are not fully supported
//~^ WARN type parameter `γ` should have a camel case name such as `Γ`
//~^ WARN type parameter `γ` should have a camel case name
>() {}

struct X {
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/utf8_idents.stderr
Expand Up @@ -30,11 +30,11 @@ LL | let α = 0.00001f64; //~ ERROR non-ascii idents are not fully supported
|
= help: add #![feature(non_ascii_idents)] to the crate attributes to enable

warning: type parameter `γ` should have a camel case name such as `Γ`
warning: type parameter `γ` should have a camel case name
--> $DIR/utf8_idents.rs:5:5
|
LL | γ //~ ERROR non-ascii idents are not fully supported
| ^
| ^ help: convert the identifier to camel case: `Γ`
|
= note: #[warn(non_camel_case_types)] on by default

Expand Down

0 comments on commit 1b28f5a

Please sign in to comment.