Skip to content

Commit

Permalink
Add new lint: trait_method_unsafe_added (#605) (#608)
Browse files Browse the repository at this point in the history
  • Loading branch information
jw013 authored Dec 13, 2023
1 parent dc54312 commit 155c283
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_added.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
SemverQuery(
id: "trait_method_unsafe_added",
human_readable_name: "pub trait method became unsafe",
description: "A method in a public trait became unsafe",
required_update: Major,
reference_link: Some("https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html#calling-an-unsafe-function-or-method"),
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 became `unsafe`, so implementing it now requires an `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 @@ -521,4 +521,5 @@ add_lints!(
module_missing,
trait_removed_associated_constant,
function_changed_abi,
trait_method_unsafe_added,
);
7 changes: 7 additions & 0 deletions test_crates/trait_method_unsafe_added/new/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
publish = false
name = "trait_method_unsafe_added"
version = "0.1.0"
edition = "2021"

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

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

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

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

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

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

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

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

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

// Private trait's method becomes unsafe, shouldn't get reported.
trait PrivateTrait {
fn becomes_unsafe();
}
24 changes: 24 additions & 0 deletions test_outputs/trait_method_unsafe_added.output.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"./test_crates/trait_method_unsafe_added/": [
{
"method_name": String("becomes_unsafe"),
"path": List([
String("trait_method_unsafe_added"),
String("PubTrait"),
]),
"span_begin_line": Uint64(3),
"span_filename": String("src/lib.rs"),
"visibility_limit": String("public"),
},
{
"method_name": String("becomes_unsafe"),
"path": List([
String("trait_method_unsafe_added"),
String("TraitBecomesUnsafe"),
]),
"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 @@ -35,6 +35,18 @@
"visibility_limit": String("public"),
},
],
"./test_crates/trait_method_unsafe_added/": [
{
"name": String("TraitBecomesPrivate"),
"path": List([
String("trait_method_unsafe_added"),
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_added.output.ron
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
{
"./test_crates/trait_method_unsafe_added/": [
{
"name": String("TraitBecomesUnsafe"),
"path": List([
String("trait_method_unsafe_added"),
String("TraitBecomesUnsafe"),
]),
"span_begin_line": Uint64(23),
"span_filename": String("src/lib.rs"),
"visibility_limit": String("public"),
},
],
"./test_crates/trait_missing/": [
{
"name": String("TraitBecomesUnsafe"),
Expand Down

0 comments on commit 155c283

Please sign in to comment.