From 8af671cc32f162057af4a595eefbb7b2b419ba90 Mon Sep 17 00:00:00 2001 From: Milo Moisson Date: Tue, 27 Aug 2024 10:06:56 +0200 Subject: [PATCH 1/3] feat: add trait_associated_type_default_removed lint --- .../trait_associated_type_default_removed.ron | 59 +++++++++++++++++++ src/query.rs | 1 + .../new/Cargo.toml | 7 +++ .../new/src/lib.rs | 25 ++++++++ .../old/Cargo.toml | 7 +++ .../old/src/lib.rs | 25 ++++++++ ...associated_type_default_removed.output.ron | 5 ++ 7 files changed, 129 insertions(+) create mode 100644 src/lints/trait_associated_type_default_removed.ron create mode 100644 test_crates/trait_associated_type_default_removed/new/Cargo.toml create mode 100644 test_crates/trait_associated_type_default_removed/new/src/lib.rs create mode 100644 test_crates/trait_associated_type_default_removed/old/Cargo.toml create mode 100644 test_crates/trait_associated_type_default_removed/old/src/lib.rs create mode 100644 test_outputs/trait_associated_type_default_removed.output.ron diff --git a/src/lints/trait_associated_type_default_removed.ron b/src/lints/trait_associated_type_default_removed.ron new file mode 100644 index 00000000..3b300d44 --- /dev/null +++ b/src/lints/trait_associated_type_default_removed.ron @@ -0,0 +1,59 @@ +SemverQuery( + id: "trait_associated_type_default_removed", + human_readable_name: "non-sealed trait removed the default value for an associated type", + description: "A non-sealed trait associated type lost its default value, which breaks downstream implementations of the trait", + required_update: Major, + lint_level: Deny, + reference_link: Some("https://doc.rust-lang.org/cargo/reference/semver.html#trait-item-signature"), + query: r#" + { + CrateDiff { + current { + item { + ... on Trait { + visibility_limit @filter(op: "=", value: ["$public"]) + + importable_path { + path @output @tag + public_api @filter(op: "=", value: ["$true"]) + } + + associated_type { + associated_type: name @output @tag + has_default @filter(op: "!=", value: ["$true"]) @output + + 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"]) + } + + associated_type { + name @filter(op: "=", value: ["%associated_type"]) + has_default @filter(op: "=", value: ["$true"]) + } + } + } + } + } + }"#, + arguments: { + "public": "public", + "true": true, + }, + error_message: "A non-sealed trait associated type lost its default value, which breaks downstream implementations of the trait", + per_result_error_template: Some("trait type {{join \"::\" path}}::{{associated_type}} in file {{span_filename}}:{{span_begin_line}}"), +) diff --git a/src/query.rs b/src/query.rs index 16bfdbe0..79a1f1cd 100644 --- a/src/query.rs +++ b/src/query.rs @@ -837,6 +837,7 @@ add_lints!( trait_associated_const_default_removed, trait_associated_const_now_doc_hidden, trait_associated_type_added, + trait_associated_type_default_removed, trait_associated_type_now_doc_hidden, trait_default_impl_removed, trait_method_missing, diff --git a/test_crates/trait_associated_type_default_removed/new/Cargo.toml b/test_crates/trait_associated_type_default_removed/new/Cargo.toml new file mode 100644 index 00000000..94022392 --- /dev/null +++ b/test_crates/trait_associated_type_default_removed/new/Cargo.toml @@ -0,0 +1,7 @@ +[package] +publish = false +name = "trait_associated_type_default_removed" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/trait_associated_type_default_removed/new/src/lib.rs b/test_crates/trait_associated_type_default_removed/new/src/lib.rs new file mode 100644 index 00000000..0dba3997 --- /dev/null +++ b/test_crates/trait_associated_type_default_removed/new/src/lib.rs @@ -0,0 +1,25 @@ +mod sealed { + pub(crate) trait Sealed {} +} + +pub trait WillLoseDefault { + type Foo; +} + +pub trait WillLoseDefaultSealed: sealed::Sealed { + type Foo; +} + +pub trait Unchanged { + type Foo = bool; +} +pub trait UnchangedSealed: sealed::Sealed { + type Foo = bool; +} + +pub trait UnchangedNoDefault { + type Foo; +} +pub trait UnchangedNoDefaultSealed: sealed::Sealed { + type Foo; +} diff --git a/test_crates/trait_associated_type_default_removed/old/Cargo.toml b/test_crates/trait_associated_type_default_removed/old/Cargo.toml new file mode 100644 index 00000000..94022392 --- /dev/null +++ b/test_crates/trait_associated_type_default_removed/old/Cargo.toml @@ -0,0 +1,7 @@ +[package] +publish = false +name = "trait_associated_type_default_removed" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/trait_associated_type_default_removed/old/src/lib.rs b/test_crates/trait_associated_type_default_removed/old/src/lib.rs new file mode 100644 index 00000000..22df46e1 --- /dev/null +++ b/test_crates/trait_associated_type_default_removed/old/src/lib.rs @@ -0,0 +1,25 @@ +mod sealed { + pub(crate) trait Sealed {} +} + +pub trait WillLoseDefault { + type Foo = bool; +} + +pub trait WillLoseDefaultSealed: sealed::Sealed { + type Foo = bool; +} + +pub trait Unchanged { + type Foo = bool; +} +pub trait UnchangedSealed: sealed::Sealed { + type Foo = bool; +} + +pub trait UnchangedNoDefault { + type Foo; +} +pub trait UnchangedNoDefaultSealed: sealed::Sealed { + type Foo; +} diff --git a/test_outputs/trait_associated_type_default_removed.output.ron b/test_outputs/trait_associated_type_default_removed.output.ron new file mode 100644 index 00000000..4f9f365a --- /dev/null +++ b/test_outputs/trait_associated_type_default_removed.output.ron @@ -0,0 +1,5 @@ +{ + "./test_crates/trait_associated_type_default_removed/": [ + // TODO + ] +} From 3639fd6b337d20b345c16f7d8e012d9a63a12723 Mon Sep 17 00:00:00 2001 From: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com> Date: Tue, 27 Aug 2024 09:29:08 -0400 Subject: [PATCH 2/3] Enable assoc type defaults unstable feature in test crates. --- .../trait_associated_type_default_removed/new/src/lib.rs | 2 ++ .../trait_associated_type_default_removed/old/src/lib.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/test_crates/trait_associated_type_default_removed/new/src/lib.rs b/test_crates/trait_associated_type_default_removed/new/src/lib.rs index 0dba3997..097cbb8a 100644 --- a/test_crates/trait_associated_type_default_removed/new/src/lib.rs +++ b/test_crates/trait_associated_type_default_removed/new/src/lib.rs @@ -1,3 +1,5 @@ +#![feature(associated_type_defaults)] + mod sealed { pub(crate) trait Sealed {} } diff --git a/test_crates/trait_associated_type_default_removed/old/src/lib.rs b/test_crates/trait_associated_type_default_removed/old/src/lib.rs index 22df46e1..4f83cbc5 100644 --- a/test_crates/trait_associated_type_default_removed/old/src/lib.rs +++ b/test_crates/trait_associated_type_default_removed/old/src/lib.rs @@ -1,3 +1,5 @@ +#![feature(associated_type_defaults)] + mod sealed { pub(crate) trait Sealed {} } From 7e587bf845d02b2ddd914fe406ac6c25a345ee9d Mon Sep 17 00:00:00 2001 From: Milo Moisson Date: Wed, 28 Aug 2024 09:15:35 +0200 Subject: [PATCH 3/3] bless tests --- ...rait_associated_type_default_removed.output.ron | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/test_outputs/trait_associated_type_default_removed.output.ron b/test_outputs/trait_associated_type_default_removed.output.ron index 4f9f365a..d3615063 100644 --- a/test_outputs/trait_associated_type_default_removed.output.ron +++ b/test_outputs/trait_associated_type_default_removed.output.ron @@ -1,5 +1,15 @@ { "./test_crates/trait_associated_type_default_removed/": [ - // TODO - ] + { + "associated_type": String("Foo"), + "has_default": Boolean(false), + "path": List([ + String("trait_associated_type_default_removed"), + String("WillLoseDefault"), + ]), + "span_begin_line": Uint64(8), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + ], }