From 537d9b259fa8cc4087571af643e5efde27fe211b Mon Sep 17 00:00:00 2001 From: Milo Moisson Date: Wed, 28 Aug 2024 21:29:27 +0200 Subject: [PATCH 1/6] feat: add trait_added_supertrait --- src/lints/trait_added_supertrait.ron | 58 ++++++++++++++++++ src/query.rs | 1 + .../trait_added_supertrait/new/Cargo.toml | 7 +++ .../trait_added_supertrait/new/src/lib.rs | 15 +++++ .../trait_added_supertrait/old/Cargo.toml | 7 +++ .../trait_added_supertrait/old/src/lib.rs | 15 +++++ .../trait_added_supertrait.output.ron | 60 +++++++++++++++++++ 7 files changed, 163 insertions(+) create mode 100644 src/lints/trait_added_supertrait.ron create mode 100644 test_crates/trait_added_supertrait/new/Cargo.toml create mode 100644 test_crates/trait_added_supertrait/new/src/lib.rs create mode 100644 test_crates/trait_added_supertrait/old/Cargo.toml create mode 100644 test_crates/trait_added_supertrait/old/src/lib.rs create mode 100644 test_outputs/trait_added_supertrait.output.ron diff --git a/src/lints/trait_added_supertrait.ron b/src/lints/trait_added_supertrait.ron new file mode 100644 index 00000000..ec9881b4 --- /dev/null +++ b/src/lints/trait_added_supertrait.ron @@ -0,0 +1,58 @@ +SemverQuery( + id: "trait_added_supertrait", + human_readable_name: "non-sealed trait added new supertraits", + description: "A non-sealed trait added one or more supertraits, which breaks downstream implementations of the trait", + required_update: Major, + lint_level: Deny, + reference_link: None, // TODO + query: r#" + { + CrateDiff { + current { + item { + ... on Trait { + visibility_limit @filter(op: "=", value: ["$public"]) + + importable_path { + path @output @tag + public_api @filter(op: "=", value: ["$true"]) + } + + supertrait { + supertrait: name @output @tag + } + + span_: span @optional { + filename @output + begin_line @output + } + } + } + } + baseline { + item { + ... on Trait { + visibility_limit @filter(op: "=", value: ["$public"]) @output + sealed @filter(op: "!=", value: ["$true"]) + + importable_path { + path @filter(op: "=", value: ["%path"]) + public_api @filter(op: "=", value: ["$true"]) + } + + supertrait @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) { + name @filter(op: "=", value: ["%supertrait"]) + } + } + } + } + } + }"#, + arguments: { + "public": "public", + "true": true, + "zero": 0, + }, + error_message: "A non-sealed trait added one or more supertraits, which breaks downstream implementations of the trait", + per_result_error_template: Some("trait {{join \"::\" path}} has gained {{supertrait}} in file {{span_filename}}:{{span_begin_line}}"), +) diff --git a/src/query.rs b/src/query.rs index e9c23923..223d4abb 100644 --- a/src/query.rs +++ b/src/query.rs @@ -1077,6 +1077,7 @@ add_lints!( struct_pub_field_now_doc_hidden, struct_repr_transparent_removed, struct_with_pub_fields_changed_type, + trait_added_supertrait, trait_associated_const_added, trait_associated_const_default_removed, trait_associated_const_now_doc_hidden, diff --git a/test_crates/trait_added_supertrait/new/Cargo.toml b/test_crates/trait_added_supertrait/new/Cargo.toml new file mode 100644 index 00000000..9368536f --- /dev/null +++ b/test_crates/trait_added_supertrait/new/Cargo.toml @@ -0,0 +1,7 @@ +[package] +publish = false +name = "trait_added_supertrait" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/trait_added_supertrait/new/src/lib.rs b/test_crates/trait_added_supertrait/new/src/lib.rs new file mode 100644 index 00000000..6cb3454d --- /dev/null +++ b/test_crates/trait_added_supertrait/new/src/lib.rs @@ -0,0 +1,15 @@ +mod sealed { + pub trait Sealed {} +} + +pub trait TraitOne {} +pub trait TraitTwo {} + +pub trait Unchanged {} +pub trait UnchangedSealed: sealed::Sealed {} + +pub trait WillGailOne: TraitOne {} +pub trait WillGailOneSealed: TraitOne + sealed::Sealed {} + +pub trait WillGailAnotherOne: TraitOne + TraitTwo {} +pub trait WillGailAnotherOneSealed: TraitOne + TraitTwo + sealed::Sealed {} diff --git a/test_crates/trait_added_supertrait/old/Cargo.toml b/test_crates/trait_added_supertrait/old/Cargo.toml new file mode 100644 index 00000000..9368536f --- /dev/null +++ b/test_crates/trait_added_supertrait/old/Cargo.toml @@ -0,0 +1,7 @@ +[package] +publish = false +name = "trait_added_supertrait" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/trait_added_supertrait/old/src/lib.rs b/test_crates/trait_added_supertrait/old/src/lib.rs new file mode 100644 index 00000000..e82ccf6f --- /dev/null +++ b/test_crates/trait_added_supertrait/old/src/lib.rs @@ -0,0 +1,15 @@ +mod sealed { + pub trait Sealed {} +} + +pub trait TraitOne {} +pub trait TraitTwo {} + +pub trait Unchanged {} +pub trait UnchangedSealed: sealed::Sealed {} + +pub trait WillGailOne {} +pub trait WillGailOneSealed: sealed::Sealed {} + +pub trait WillGailAnotherOne: TraitOne {} +pub trait WillGailAnotherOneSealed: TraitOne + sealed::Sealed {} diff --git a/test_outputs/trait_added_supertrait.output.ron b/test_outputs/trait_added_supertrait.output.ron new file mode 100644 index 00000000..f96b67a0 --- /dev/null +++ b/test_outputs/trait_added_supertrait.output.ron @@ -0,0 +1,60 @@ +{ + "./test_crates/trait_added_supertrait/": [ + { + "path": List([ + String("trait_added_supertrait"), + String("WillGailOne"), + ]), + "span_begin_line": Uint64(11), + "span_filename": String("src/lib.rs"), + "supertrait": String("TraitOne"), + "visibility_limit": String("public"), + }, + { + "path": List([ + String("trait_added_supertrait"), + String("WillGailAnotherOne"), + ]), + "span_begin_line": Uint64(14), + "span_filename": String("src/lib.rs"), + "supertrait": String("TraitTwo"), + "visibility_limit": String("public"), + }, + ], + "./test_crates/trait_associated_const_added/": [ + { + "path": List([ + String("trait_associated_const_added"), + String("WillGainConstWithoutDefaultAndSeal"), + ]), + "span_begin_line": Uint64(16), + "span_filename": String("src/lib.rs"), + "supertrait": String("sealed::Sealed"), + "visibility_limit": String("public"), + }, + ], + "./test_crates/trait_associated_type_added/": [ + { + "path": List([ + String("trait_associated_type_added"), + String("WillGainTypeWithoutDefaultAndSeal"), + ]), + "span_begin_line": Uint64(19), + "span_filename": String("src/lib.rs"), + "supertrait": String("sealed::Sealed"), + "visibility_limit": String("public"), + }, + ], + "./test_crates/trait_newly_sealed/": [ + { + "path": List([ + String("trait_newly_sealed"), + String("TraitBecomesSealed"), + ]), + "span_begin_line": Uint64(7), + "span_filename": String("src/lib.rs"), + "supertrait": String("private::Sealed"), + "visibility_limit": String("public"), + }, + ], +} From f6c52f876206bdb73d4398edfefc4c2d03b07e8c Mon Sep 17 00:00:00 2001 From: Milo Moisson Date: Wed, 28 Aug 2024 21:58:55 +0200 Subject: [PATCH 2/6] review --- src/lints/trait_added_supertrait.ron | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lints/trait_added_supertrait.ron b/src/lints/trait_added_supertrait.ron index ec9881b4..f49b1d9a 100644 --- a/src/lints/trait_added_supertrait.ron +++ b/src/lints/trait_added_supertrait.ron @@ -4,7 +4,7 @@ SemverQuery( description: "A non-sealed trait added one or more supertraits, which breaks downstream implementations of the trait", required_update: Major, lint_level: Deny, - reference_link: None, // TODO + reference_link: Some("doc.rust-lang.org/cargo/reference/semver.html#generic-bounds-tighten"), query: r#" { CrateDiff { @@ -54,5 +54,5 @@ SemverQuery( "zero": 0, }, error_message: "A non-sealed trait added one or more supertraits, which breaks downstream implementations of the trait", - per_result_error_template: Some("trait {{join \"::\" path}} has gained {{supertrait}} in file {{span_filename}}:{{span_begin_line}}"), + per_result_error_template: Some("trait {{join \"::\" path}} gained {{supertrait}} in file {{span_filename}}:{{span_begin_line}}"), ) From 46df55909e065435caaa6932a688eacc06bdbfbe Mon Sep 17 00:00:00 2001 From: Milo Moisson Date: Wed, 28 Aug 2024 23:15:01 +0200 Subject: [PATCH 3/6] typo and std supertraits --- .../trait_added_supertrait/new/src/lib.rs | 20 ++++++++++++------- .../trait_added_supertrait/old/src/lib.rs | 20 ++++++++++++------- .../trait_added_supertrait.output.ron | 4 ++-- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/test_crates/trait_added_supertrait/new/src/lib.rs b/test_crates/trait_added_supertrait/new/src/lib.rs index 6cb3454d..22b067b2 100644 --- a/test_crates/trait_added_supertrait/new/src/lib.rs +++ b/test_crates/trait_added_supertrait/new/src/lib.rs @@ -1,15 +1,21 @@ +pub trait TraitOne {} +pub trait TraitTwo {} + mod sealed { pub trait Sealed {} } -pub trait TraitOne {} -pub trait TraitTwo {} - pub trait Unchanged {} pub trait UnchangedSealed: sealed::Sealed {} -pub trait WillGailOne: TraitOne {} -pub trait WillGailOneSealed: TraitOne + sealed::Sealed {} +pub trait WillGainOne: TraitOne {} +pub trait WillGainOneSealed: TraitOne + sealed::Sealed {} -pub trait WillGailAnotherOne: TraitOne + TraitTwo {} -pub trait WillGailAnotherOneSealed: TraitOne + TraitTwo + sealed::Sealed {} +pub trait WillGainAnotherOne: TraitOne + TraitTwo {} +pub trait WillGainAnotherOneSealed: TraitOne + TraitTwo + sealed::Sealed {} + +pub trait WillGainStdOne: Sync {} +pub trait WillGainStdTwo: core::fmt::Debug {} +pub trait WillGainStdThree: PartialEq { + fn make_me_non_object_safe() -> Self; +} diff --git a/test_crates/trait_added_supertrait/old/src/lib.rs b/test_crates/trait_added_supertrait/old/src/lib.rs index e82ccf6f..8c10d0e2 100644 --- a/test_crates/trait_added_supertrait/old/src/lib.rs +++ b/test_crates/trait_added_supertrait/old/src/lib.rs @@ -1,15 +1,21 @@ +pub trait TraitOne {} +pub trait TraitTwo {} + mod sealed { pub trait Sealed {} } -pub trait TraitOne {} -pub trait TraitTwo {} - pub trait Unchanged {} pub trait UnchangedSealed: sealed::Sealed {} -pub trait WillGailOne {} -pub trait WillGailOneSealed: sealed::Sealed {} +pub trait WillGainOne {} +pub trait WillGainOneSealed: sealed::Sealed {} -pub trait WillGailAnotherOne: TraitOne {} -pub trait WillGailAnotherOneSealed: TraitOne + sealed::Sealed {} +pub trait WillGainAnotherOne: TraitOne {} +pub trait WillGainAnotherOneSealed: TraitOne + sealed::Sealed {} + +pub trait WillGainStdOne {} +pub trait WillGainStdTwo {} +pub trait WillGainStdThree { + fn make_me_non_object_safe() -> Self; +} diff --git a/test_outputs/trait_added_supertrait.output.ron b/test_outputs/trait_added_supertrait.output.ron index f96b67a0..b6d3011d 100644 --- a/test_outputs/trait_added_supertrait.output.ron +++ b/test_outputs/trait_added_supertrait.output.ron @@ -3,7 +3,7 @@ { "path": List([ String("trait_added_supertrait"), - String("WillGailOne"), + String("WillGainOne"), ]), "span_begin_line": Uint64(11), "span_filename": String("src/lib.rs"), @@ -13,7 +13,7 @@ { "path": List([ String("trait_added_supertrait"), - String("WillGailAnotherOne"), + String("WillGainAnotherOne"), ]), "span_begin_line": Uint64(14), "span_filename": String("src/lib.rs"), From 3ea076683a0bd6943d7cdc024c35ddcf550d785e Mon Sep 17 00:00:00 2001 From: Milo Moisson Date: Fri, 20 Sep 2024 13:51:19 +0200 Subject: [PATCH 4/6] add std to core supertrait test --- test_crates/trait_added_supertrait/new/src/lib.rs | 2 ++ test_crates/trait_added_supertrait/old/src/lib.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/test_crates/trait_added_supertrait/new/src/lib.rs b/test_crates/trait_added_supertrait/new/src/lib.rs index 22b067b2..7f4770d8 100644 --- a/test_crates/trait_added_supertrait/new/src/lib.rs +++ b/test_crates/trait_added_supertrait/new/src/lib.rs @@ -19,3 +19,5 @@ pub trait WillGainStdTwo: core::fmt::Debug {} pub trait WillGainStdThree: PartialEq { fn make_me_non_object_safe() -> Self; } + +pub trait WillChangeStdToCore: core::fmt::Debug {} diff --git a/test_crates/trait_added_supertrait/old/src/lib.rs b/test_crates/trait_added_supertrait/old/src/lib.rs index 8c10d0e2..c41c3171 100644 --- a/test_crates/trait_added_supertrait/old/src/lib.rs +++ b/test_crates/trait_added_supertrait/old/src/lib.rs @@ -19,3 +19,5 @@ pub trait WillGainStdTwo {} pub trait WillGainStdThree { fn make_me_non_object_safe() -> Self; } + +pub trait WillChangeStdToCore: std::fmt::Debug {} From 95a038b15fe2f4627de2099e1d3c3bb0fcf557d0 Mon Sep 17 00:00:00 2001 From: Milo Moisson Date: Fri, 20 Sep 2024 13:51:26 +0200 Subject: [PATCH 5/6] bless tests --- .../trait_added_supertrait.output.ron | 48 +++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/test_outputs/trait_added_supertrait.output.ron b/test_outputs/trait_added_supertrait.output.ron index b6d3011d..bc16d62d 100644 --- a/test_outputs/trait_added_supertrait.output.ron +++ b/test_outputs/trait_added_supertrait.output.ron @@ -20,6 +20,36 @@ "supertrait": String("TraitTwo"), "visibility_limit": String("public"), }, + { + "path": List([ + String("trait_added_supertrait"), + String("WillGainStdOne"), + ]), + "span_begin_line": Uint64(17), + "span_filename": String("src/lib.rs"), + "supertrait": String("Sync"), + "visibility_limit": String("public"), + }, + { + "path": List([ + String("trait_added_supertrait"), + String("WillGainStdTwo"), + ]), + "span_begin_line": Uint64(18), + "span_filename": String("src/lib.rs"), + "supertrait": String("Debug"), + "visibility_limit": String("public"), + }, + { + "path": List([ + String("trait_added_supertrait"), + String("WillGainStdThree"), + ]), + "span_begin_line": Uint64(19), + "span_filename": String("src/lib.rs"), + "supertrait": String("PartialEq"), + "visibility_limit": String("public"), + }, ], "./test_crates/trait_associated_const_added/": [ { @@ -29,7 +59,7 @@ ]), "span_begin_line": Uint64(16), "span_filename": String("src/lib.rs"), - "supertrait": String("sealed::Sealed"), + "supertrait": String("Sealed"), "visibility_limit": String("public"), }, ], @@ -41,7 +71,19 @@ ]), "span_begin_line": Uint64(19), "span_filename": String("src/lib.rs"), - "supertrait": String("sealed::Sealed"), + "supertrait": String("Sealed"), + "visibility_limit": String("public"), + }, + ], + "./test_crates/trait_method_added/": [ + { + "path": List([ + String("trait_method_added"), + String("WillGainMethodWithoutDefaultAndSeal"), + ]), + "span_begin_line": Uint64(20), + "span_filename": String("src/lib.rs"), + "supertrait": String("Sealed"), "visibility_limit": String("public"), }, ], @@ -53,7 +95,7 @@ ]), "span_begin_line": Uint64(7), "span_filename": String("src/lib.rs"), - "supertrait": String("private::Sealed"), + "supertrait": String("Sealed"), "visibility_limit": String("public"), }, ], From 3e893cb3f1e4694acaf8cf2d088c6e0912e49a7b Mon Sep 17 00:00:00 2001 From: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com> Date: Fri, 20 Sep 2024 12:00:24 -0400 Subject: [PATCH 6/6] Update src/lints/trait_added_supertrait.ron Co-authored-by: Max Carr --- src/lints/trait_added_supertrait.ron | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lints/trait_added_supertrait.ron b/src/lints/trait_added_supertrait.ron index f49b1d9a..e842809a 100644 --- a/src/lints/trait_added_supertrait.ron +++ b/src/lints/trait_added_supertrait.ron @@ -4,7 +4,7 @@ SemverQuery( description: "A non-sealed trait added one or more supertraits, which breaks downstream implementations of the trait", required_update: Major, lint_level: Deny, - reference_link: Some("doc.rust-lang.org/cargo/reference/semver.html#generic-bounds-tighten"), + reference_link: Some("https://doc.rust-lang.org/cargo/reference/semver.html#generic-bounds-tighten"), query: r#" { CrateDiff {