Skip to content

Commit

Permalink
Add new lint: trait_method_unsafe_removed (#612)
Browse files Browse the repository at this point in the history
* Add new lint: trait_method_unsafe_removed

* Create tests for lint trait_method_unsafe_removed

* Implement lint trait_method_unsafe_removed
  • Loading branch information
yottalogical authored Dec 21, 2023
1 parent 27e3c9c commit 58711ac
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 0 deletions.
59 changes: 59 additions & 0 deletions src/lints/trait_method_unsafe_removed.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
SemverQuery(
id: "trait_method_unsafe_removed",
human_readable_name: "pub trait method became safe",
description: "A method in a public trait became safe",
required_update: Major,
reference_link: Some("https://doc.rust-lang.org/stable/reference/unsafe-keyword.html#unsafe-functions-unsafe-fn"),
query: r#"
{
CrateDiff {
baseline {
item {
... on Trait {
visibility_limit @filter(op: "=", value: ["$public"]) @output
importable_path {
path @output @tag
public_api @filter(op: "=", value: ["$true"])
}
method {
unsafe @filter(op: "=", value: ["$true"])
public_api_eligible @filter(op: "=", value: ["$true"])
method_name: name @output @tag
}
}
}
}
current {
item {
... on Trait {
visibility_limit @filter(op: "=", value: ["$public"])
importable_path {
path @filter(op: "=", value: ["%path"])
public_api @filter(op: "=", value: ["$true"])
}
method {
unsafe @filter(op: "!=", value: ["$true"])
public_api_eligible @filter(op: "=", value: ["$true"])
name @filter(op: "=", value: ["%method_name"])
span_: span @optional {
filename @output
begin_line @output
}
}
}
}
}
}
}"#,
arguments: {
"true": true,
"public": "public",
},
error_message: "A publicly-visible trait method is no longer `unsafe`, so implementations must remove the `unsafe` qualifier.",
per_result_error_template: Some("trait method <{{join \"::\" path}}>::{{method_name}} in file {{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 @@ -522,4 +522,5 @@ add_lints!(
trait_removed_associated_constant,
function_changed_abi,
trait_method_unsafe_added,
trait_method_unsafe_removed,
);
7 changes: 7 additions & 0 deletions test_crates/trait_method_unsafe_removed/new/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
publish = false
name = "trait_method_unsafe_removed"
version = "0.1.0"
edition = "2021"

[dependencies]
30 changes: 30 additions & 0 deletions test_crates/trait_method_unsafe_removed/new/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Method of public trait becomes safe, should get reported.
pub trait PubTrait {
fn becomes_safe();
fn stays_safe();
unsafe fn stays_unsafe();
}

// Method of trait that was not publicly-visible becomes safe, shouldn't get
// reported.
pub trait TraitBecomesPublic {
fn becomes_safe();
}

// Method of trait that is publicly-visible becomes safe while trait becomes
// private. The trait becoming private should be the only violation that's
// reported.
trait TraitBecomesPrivate {
fn becomes_safe();
}

// Method of trait becomes safe while trait also becomes safe. Method should get
// reported along with trait.
pub trait TraitBecomesSafe {
fn becomes_safe();
}

// Private trait's method becomes safe, shouldn't get reported.
trait PrivateTrait {
fn becomes_safe();
}
7 changes: 7 additions & 0 deletions test_crates/trait_method_unsafe_removed/old/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
publish = false
name = "trait_method_unsafe_removed"
version = "0.1.0"
edition = "2021"

[dependencies]
30 changes: 30 additions & 0 deletions test_crates/trait_method_unsafe_removed/old/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Method of public trait becomes safe, should get reported.
pub trait PubTrait {
unsafe fn becomes_safe();
fn stays_safe();
unsafe fn stays_unsafe();
}

// Method of trait that was not publicly-visible becomes safe, shouldn't get
// reported.
trait TraitBecomesPublic {
unsafe fn becomes_safe();
}

// Method of trait that is publicly-visible becomes safe while trait becomes
// private. The trait becoming private should be the only violation that's
// reported.
pub trait TraitBecomesPrivate {
unsafe fn becomes_safe();
}

// Method of trait becomes safe while trait also becomes safe. Method should get
// reported along with trait.
pub unsafe trait TraitBecomesSafe {
unsafe fn becomes_safe();
}

// Private trait's method becomes safe, shouldn't get reported.
trait PrivateTrait {
unsafe fn becomes_safe();
}
24 changes: 24 additions & 0 deletions test_outputs/trait_method_unsafe_removed.output.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"./test_crates/trait_method_unsafe_removed/": [
{
"method_name": String("becomes_safe"),
"path": List([
String("trait_method_unsafe_removed"),
String("PubTrait"),
]),
"span_begin_line": Uint64(3),
"span_filename": String("src/lib.rs"),
"visibility_limit": String("public"),
},
{
"method_name": String("becomes_safe"),
"path": List([
String("trait_method_unsafe_removed"),
String("TraitBecomesSafe"),
]),
"span_begin_line": Uint64(24),
"span_filename": String("src/lib.rs"),
"visibility_limit": String("public"),
}
],
}
12 changes: 12 additions & 0 deletions test_outputs/trait_missing.output.ron
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@
"visibility_limit": String("public"),
},
],
"./test_crates/trait_method_unsafe_removed/": [
{
"name": String("TraitBecomesPrivate"),
"path": List([
String("trait_method_unsafe_removed"),
String("TraitBecomesPrivate"),
]),
"span_begin_line": Uint64(17),
"span_filename": String("src/lib.rs"),
"visibility_limit": String("public"),
},
],
"./test_crates/trait_missing/": [
{
"name": String("RemovedTrait"),
Expand Down
12 changes: 12 additions & 0 deletions test_outputs/trait_unsafe_removed.output.ron
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,16 @@
"visibility_limit": String("public"),
},
],
"./test_crates/trait_method_unsafe_removed/": [
{
"name": String("TraitBecomesSafe"),
"path": List([
String("trait_method_unsafe_removed"),
String("TraitBecomesSafe"),
]),
"span_begin_line": Uint64(23),
"span_filename": String("src/lib.rs"),
"visibility_limit": String("public"),
},
],
}

0 comments on commit 58711ac

Please sign in to comment.