-
-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
trait_mismatched_generic_lifetimes
lint. (#1040)
Analogous to #1039, but this time for traits instead of structs/enums/unions. For traits, the proof of breakage is in trait bounds where all lifetimes must be explicitly specified.
- Loading branch information
1 parent
649ae53
commit aba9737
Showing
7 changed files
with
210 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
SemverQuery( | ||
id: "trait_mismatched_generic_lifetimes", | ||
human_readable_name: "trait now takes a different number of generic lifetimes", | ||
description: "A trait now takes a different number of generic lifetime parameters, breaking uses of that trait.", | ||
required_update: Major, | ||
lint_level: Deny, | ||
// The cargo SemVer reference only has entries for generic *type* parameters. | ||
// There's no passable place to link to when it comes to specifically lifetime parameters. | ||
reference_link: None, | ||
query: r#" | ||
{ | ||
CrateDiff { | ||
baseline { | ||
item { | ||
... on Trait { | ||
visibility_limit @filter(op: "=", value: ["$public"]) | ||
name @output | ||
importable_path { | ||
path @tag @output | ||
public_api @filter(op: "=", value: ["$true"]) | ||
} | ||
generic_parameter @fold | ||
@transform(op: "count") | ||
@tag(name: "old_lifetimes_count") | ||
@output(name: "old_lifetimes_count") { | ||
... on GenericLifetimeParameter { | ||
old_lifetimes: name @output | ||
} | ||
} | ||
} | ||
} | ||
} | ||
current { | ||
item { | ||
... on Trait { | ||
visibility_limit @filter(op: "=", value: ["$public"]) @output | ||
importable_path { | ||
path @filter(op: "=", value: ["%path"]) | ||
public_api @filter(op: "=", value: ["$true"]) | ||
} | ||
generic_parameter @fold | ||
@transform(op: "count") | ||
@filter(op: "!=", value: ["%old_lifetimes_count"]) | ||
@output(name: "new_lifetimes_count") { | ||
... on GenericLifetimeParameter { | ||
new_lifetimes: name @output | ||
} | ||
} | ||
span_: span @optional { | ||
filename @output | ||
begin_line @output | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}"#, | ||
arguments: { | ||
"public": "public", | ||
"true": true, | ||
}, | ||
error_message: "A trait now takes a different number of generic lifetime parameters. Uses of this trait that name the previous number of parameters, such as in trait bounds, will be broken.", | ||
per_result_error_template: Some("trait {{name}} ({{old_lifetimes_count}} -> {{new_lifetimes_count}} lifetime params) in {{span_filename}}:{{span_begin_line}}"), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
test_crates/trait_mismatched_generic_lifetimes/new/Cargo.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[package] | ||
publish = false | ||
name = "trait_mismatched_generic_lifetimes" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] |
23 changes: 23 additions & 0 deletions
23
test_crates/trait_mismatched_generic_lifetimes/new/src/lib.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// All these changes are breaking. | ||
// | ||
// The best witness is using the trait in a bound: | ||
// ``` | ||
// fn witness<T: Example>() {} | ||
// ``` | ||
// where supplying any number other than the exact number of lifetime parameters is an error: | ||
// ``` | ||
// | | ||
// 6 | fn witness<T: Example>() {} | ||
// | ^^^^^^^ expected 2 lifetime parameters | ||
// | | ||
// = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html | ||
// help: consider making the bound lifetime-generic with a new `'a` lifetime | ||
// ``` | ||
|
||
pub trait NotGeneric<'a> {} | ||
|
||
pub trait GainsLifetimes<'a, 'b> {} | ||
|
||
pub trait LosesLifetimes<'a> {} | ||
|
||
pub trait StopsBeingGeneric {} |
7 changes: 7 additions & 0 deletions
7
test_crates/trait_mismatched_generic_lifetimes/old/Cargo.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[package] | ||
publish = false | ||
name = "trait_mismatched_generic_lifetimes" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] |
23 changes: 23 additions & 0 deletions
23
test_crates/trait_mismatched_generic_lifetimes/old/src/lib.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// All these changes are breaking. | ||
// | ||
// The best witness is using the trait in a bound: | ||
// ``` | ||
// fn witness<T: Example>() {} | ||
// ``` | ||
// where supplying any number other than the exact number of lifetime parameters is an error: | ||
// ``` | ||
// | | ||
// 6 | fn witness<T: Example>() {} | ||
// | ^^^^^^^ expected 2 lifetime parameters | ||
// | | ||
// = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html | ||
// help: consider making the bound lifetime-generic with a new `'a` lifetime | ||
// ``` | ||
|
||
pub trait NotGeneric {} | ||
|
||
pub trait GainsLifetimes<'a> {} | ||
|
||
pub trait LosesLifetimes<'a, 'b> {} | ||
|
||
pub trait StopsBeingGeneric<'a, 'b> {} |
80 changes: 80 additions & 0 deletions
80
test_outputs/query_execution/trait_mismatched_generic_lifetimes.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
--- | ||
source: src/query.rs | ||
expression: "&query_execution_results" | ||
snapshot_kind: text | ||
--- | ||
{ | ||
"./test_crates/trait_mismatched_generic_lifetimes/": [ | ||
{ | ||
"name": String("NotGeneric"), | ||
"new_lifetimes": List([ | ||
String("\'a"), | ||
]), | ||
"new_lifetimes_count": Uint64(1), | ||
"old_lifetimes": List([]), | ||
"old_lifetimes_count": Uint64(0), | ||
"path": List([ | ||
String("trait_mismatched_generic_lifetimes"), | ||
String("NotGeneric"), | ||
]), | ||
"span_begin_line": Uint64(17), | ||
"span_filename": String("src/lib.rs"), | ||
"visibility_limit": String("public"), | ||
}, | ||
{ | ||
"name": String("GainsLifetimes"), | ||
"new_lifetimes": List([ | ||
String("\'a"), | ||
String("\'b"), | ||
]), | ||
"new_lifetimes_count": Uint64(2), | ||
"old_lifetimes": List([ | ||
String("\'a"), | ||
]), | ||
"old_lifetimes_count": Uint64(1), | ||
"path": List([ | ||
String("trait_mismatched_generic_lifetimes"), | ||
String("GainsLifetimes"), | ||
]), | ||
"span_begin_line": Uint64(19), | ||
"span_filename": String("src/lib.rs"), | ||
"visibility_limit": String("public"), | ||
}, | ||
{ | ||
"name": String("LosesLifetimes"), | ||
"new_lifetimes": List([ | ||
String("\'a"), | ||
]), | ||
"new_lifetimes_count": Uint64(1), | ||
"old_lifetimes": List([ | ||
String("\'a"), | ||
String("\'b"), | ||
]), | ||
"old_lifetimes_count": Uint64(2), | ||
"path": List([ | ||
String("trait_mismatched_generic_lifetimes"), | ||
String("LosesLifetimes"), | ||
]), | ||
"span_begin_line": Uint64(21), | ||
"span_filename": String("src/lib.rs"), | ||
"visibility_limit": String("public"), | ||
}, | ||
{ | ||
"name": String("StopsBeingGeneric"), | ||
"new_lifetimes": List([]), | ||
"new_lifetimes_count": Uint64(0), | ||
"old_lifetimes": List([ | ||
String("\'a"), | ||
String("\'b"), | ||
]), | ||
"old_lifetimes_count": Uint64(2), | ||
"path": List([ | ||
String("trait_mismatched_generic_lifetimes"), | ||
String("StopsBeingGeneric"), | ||
]), | ||
"span_begin_line": Uint64(23), | ||
"span_filename": String("src/lib.rs"), | ||
"visibility_limit": String("public"), | ||
}, | ||
], | ||
} |