Skip to content

Commit

Permalink
Add lint for "deprecated" attribute on structs (obi1kenobi#365)
Browse files Browse the repository at this point in the history
* Add lint for "deprecated" attribute on structs

This was mostly done copying and adjusting code from the "must_use" attribute lint.

* Generalize lint for "deprecated" struct attribute

Now the same query also checks enums and unions.

* Rename struct_deprecated_added lint to its now more general use case

* Reduce comments, use more meaningful strings

* Add tests for deprecated enums

* Add tests for deprecated unions

Unions are not supported yet by the query engine,
so the output file doesn't change.

* Simplify deprecated lint name

* Reorganize deprecated tests

* Apply suggestions from code review

---------

Co-authored-by: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com>
  • Loading branch information
Daaiid and obi1kenobi authored Feb 12, 2023
1 parent 9b4a735 commit 4472828
Show file tree
Hide file tree
Showing 13 changed files with 439 additions and 0 deletions.
62 changes: 62 additions & 0 deletions src/lints/type_marked_deprecated.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
SemverQuery(
id: "type_marked_deprecated",
human_readable_name: "#[deprecated] added on type",
description: "A type has been newly marked with #[deprecated].",
required_update: Minor,
reference_link: Some("https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute"),
query: r#"
{
CrateDiff {
current {
item {
... on ImplOwner {
visibility_limit @filter(op: "=", value: ["$public"])
name @output
owner_type: __typename @tag @output
importable_path {
path @tag @output
}
attribute {
new_attr: raw_attribute @output
content {
base @filter(op: "=", value: ["$deprecated"])
}
}
span_: span @optional {
filename @output
begin_line @output
}
}
}
}
baseline {
item {
... on ImplOwner {
visibility_limit @filter(op: "=", value: ["$public"]) @output
__typename @filter(op: "=", value: ["%owner_type"])
importable_path {
path @filter(op: "=", value: ["%path"])
}
attribute @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) {
content {
base @filter(op: "=", value: ["$deprecated"])
}
}
}
}
}
}
}"#,
arguments: {
"public": "public",
"deprecated": "deprecated",
"zero": 0,
},
error_message: "A type is now #[deprecated]. Downstream crates will get a compiler warning when using this type.",
per_result_error_template: Some("{{owner_type}} {{name}} in {{span_filename}}:{{span_begin_line}}"),
)
1 change: 1 addition & 0 deletions src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ add_lints!(
trait_unsafe_added,
trait_unsafe_removed,
tuple_struct_to_plain_struct,
type_marked_deprecated,
unit_struct_changed_kind,
variant_marked_non_exhaustive,
);
7 changes: 7 additions & 0 deletions test_crates/type_marked_deprecated/new/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
publish = false
name = "type_marked_deprecated"
version = "0.1.0"
edition = "2021"

[dependencies]
57 changes: 57 additions & 0 deletions test_crates/type_marked_deprecated/new/src/enums.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// These enums did not have the #[deprecated] attribute in the old version.
// Addition of the attribute should be reported.

#[deprecated]
pub enum EnumToDeprecatedEnum {
First,
}

#[deprecated = "This attribute was added"]
pub enum EnumToDeprecatedMessageEnum {
First,
}

// These structs had the #[deprecated] attribute in the old version.
// They also included the user-defined warning message. Changes of
// the attribute, including deletion, should NOT be reported by this rule.

pub enum DeprecatedEnumToEnum {
First,
}

#[deprecated = "This message was added"]
pub enum DeprecatedEnumToDeprecatedMessageEnum {
First,
}

pub enum DeprecatedMessageEnumToEnum {
First,
}

#[deprecated]
pub enum DeprecatedMessageEnumToDeprecatedEnum {
First,
}

#[deprecated = "This message was changed"]
pub enum DeprecatedMessageEnumToDeprecatedMessageEnum {
First,
}

// This enum is private and should NOT be reported.

#[deprecated]
enum DeprecatedPrivateEnum {
First,
}

// This enum was added in the new version of the crate with its attribute.
// It should NOT be reported by this rule to avoid duplicate lints.
// It should be reported as a new pub type that is part of the crate's API.
// This might seem like a nonsensical test but is a valid edge case.

#[deprecated]
pub enum DeprecatedNewEnum {
First,
}

3 changes: 3 additions & 0 deletions test_crates/type_marked_deprecated/new/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod enums;
pub mod structs;
pub mod unions;
59 changes: 59 additions & 0 deletions test_crates/type_marked_deprecated/new/src/structs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// These structs did not have the #[deprecated] attribute in the old version.
// Addition of the attribute should be reported by this rule.

#[deprecated]
pub struct StructToDeprecatedStruct {
bar: u64,
}

#[deprecated = "This attribute was added"]
pub struct StructToDeprecatedMessageStruct {
bar: u64,
}

// These structs had the #[deprecated] attribute in the old version. Changes of
// the attribute, including deletion, should NOT be reported by this rule.

pub struct DeprecatedStructToStruct {
bar: u64,
}

#[deprecated = "This message was added"]
pub struct DeprecatedStructToDeprecatedMessageStruct {
bar: u64,
}

// These structs had the #[deprecated] attribute in the old version.
// They also included the user-defined warning message. Changes of
// the attribute, including deletion, should NOT be reported by this rule.

pub struct DeprecatedMessageStructToStruct {
bar: u64,
}

#[deprecated]
pub struct DeprecatedMessageStructToDeprecatedStruct {
bar: u64,
}

#[deprecated = "This message was changed"]
pub struct DeprecatedMessageStructToDeprecatedMessageStruct {
bar: u64,
}

// This struct is private and should NOT be reported by this rule.

#[deprecated]
struct DeprecatedPrivateStruct {
bar: u64,
}

// This struct was added in the new version of the crate with its attribute.
// It should NOT be reported by this rule to avoid duplicate lints.
// It should be reported as a new pub type that is part of the crate's API.
// This might seem like a nonsensical test but is a valid edge case.

#[deprecated]
pub struct DeprecatedNewStruct {
bar: u64,
}
56 changes: 56 additions & 0 deletions test_crates/type_marked_deprecated/new/src/unions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// These unions did not have the #[deprecated] attribute in the old version.
// Addition of the attribute should be reported.

#[deprecated]
pub union UnionToDeprecatedUnion {
bar: u64,
}

#[deprecated = "This attribute was added"]
pub union UnionToDeprecatedMessageUnion {
bar: u64,
}

// These structs had the #[deprecated] attribute in the old version.
// They also included the user-defined warning message. Changes of
// the attribute, including deletion, should NOT be reported by this rule.

pub union DeprecatedUnionToUnion {
bar: u64,
}

#[deprecated = "This message was added"]
pub union DeprecatedUnionToDeprecatedMessageUnion {
bar: u64,
}

pub union DeprecatedMessageUnionToUnion {
bar: u64,
}

#[deprecated]
pub union DeprecatedMessageUnionToDeprecatedUnion {
bar: u64,
}

#[deprecated = "This message was changed"]
pub union DeprecatedMessageUnionToDeprecatedMessageUnion {
bar: u64,
}

// This union is private and should NOT be reported.

#[deprecated]
union DeprecatedPrivateUnion {
bar: u64,
}

// This union was added in the new version of the crate with its attribute.
// It should NOT be reported by this rule to avoid duplicate lints.
// It should be reported as a new pub type that is part of the crate's API.
// This might seem like a nonsensical test but is a valid edge case.

#[deprecated]
pub union DeprecatedNewUnion {
bar: u64,
}
7 changes: 7 additions & 0 deletions test_crates/type_marked_deprecated/old/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
publish = false
name = "type_marked_deprecated"
version = "0.1.0"
edition = "2021"

[dependencies]
43 changes: 43 additions & 0 deletions test_crates/type_marked_deprecated/old/src/enums.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Adding #[deprecated] to these enums should be reported.

pub enum EnumToDeprecatedEnum {
First,
}

pub enum EnumToDeprecatedMessageEnum {
First,
}

// These enums already have the attribute and changes to the attribute should not be reported.

#[deprecated]
pub enum DeprecatedEnumToEnum {
First,
}

#[deprecated]
pub enum DeprecatedEnumToDeprecatedMessageEnum {
First,
}

#[deprecated = "This attribute will be deleted"]
pub enum DeprecatedMessageEnumToEnum {
First,
}

#[deprecated = "This message will be deleted"]
pub enum DeprecatedMessageEnumToDeprecatedEnum {
First,
}

#[deprecated = "This message will change"]
pub enum DeprecatedMessageEnumToDeprecatedMessageEnum {
First,
}

// This enum is private and should NOT be reported.

enum DeprecatedPrivateEnum {
First,
}

3 changes: 3 additions & 0 deletions test_crates/type_marked_deprecated/old/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod enums;
pub mod structs;
pub mod unions;
43 changes: 43 additions & 0 deletions test_crates/type_marked_deprecated/old/src/structs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Adding #[deprecated] to these structs should be reported.

pub struct StructToDeprecatedStruct {
bar: u64,
}

pub struct StructToDeprecatedMessageStruct {
bar: u64,
}

// These structs already have the attribute and changes to the attribute should not be reported.

#[deprecated]
pub struct DeprecatedStructToStruct {
bar: u64,
}

#[deprecated]
pub struct DeprecatedStructToDeprecatedMessageStruct {
bar: u64,
}

#[deprecated = "This attribute will be deleted"]
pub struct DeprecatedMessageStructToStruct {
bar: u64,
}

#[deprecated = "This message will be deleted"]
pub struct DeprecatedMessageStructToDeprecatedStruct {
bar: u64,
}

#[deprecated = "This message will change"]
pub struct DeprecatedMessageStructToDeprecatedMessageStruct {
bar: u64,
}

// This struct is private and should NOT be reported.

struct DeprecatedPrivateStruct {
bar: u64,
}

Loading

0 comments on commit 4472828

Please sign in to comment.