diff options
| author | Samuel Moelius <sam@moeli.us> | 2024-11-13 10:16:59 -0500 |
|---|---|---|
| committer | Samuel Moelius <sam@moeli.us> | 2024-11-15 17:37:10 -0500 |
| commit | d0f35777205090e24d5822e668cc280cab78e4ec (patch) | |
| tree | f3ff1070975014212d9acf53a3edb7097094b939 | |
| parent | f159a3eb1dfc3b81088fce364a09e8a79968adda (diff) | |
| download | rust-d0f35777205090e24d5822e668cc280cab78e4ec.tar.gz rust-d0f35777205090e24d5822e668cc280cab78e4ec.zip | |
Properly handle `disallowed_types`
6 files changed, 58 insertions, 15 deletions
diff --git a/clippy_config/src/types.rs b/clippy_config/src/types.rs index 70d9073b59c..122fdca726d 100644 --- a/clippy_config/src/types.rs +++ b/clippy_config/src/types.rs @@ -47,7 +47,7 @@ impl DisallowedPath { } } - pub fn reason(&self) -> Option<&str> { + fn reason(&self) -> Option<&str> { match &self { Self::WithReason { reason, .. } => reason.as_deref(), Self::Simple(_) => None, diff --git a/clippy_lints/src/disallowed_types.rs b/clippy_lints/src/disallowed_types.rs index 3265404f2b2..a34ec4616e5 100644 --- a/clippy_lints/src/disallowed_types.rs +++ b/clippy_lints/src/disallowed_types.rs @@ -1,4 +1,5 @@ use clippy_config::Conf; +use clippy_config::types::DisallowedPath; use clippy_utils::diagnostics::span_lint_and_then; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::Res; @@ -31,7 +32,8 @@ declare_clippy_lint! { /// # When using an inline table, can add a `reason` for why the type /// # is disallowed. /// { path = "std::net::Ipv4Addr", reason = "no IPv4 allowed" }, - /// ] + /// # Can also add a `replacement` that will be offered as a suggestion. + /// { path = "std::sync::Mutex", reason = "prefer faster & simpler non-poisonable mutex", replacement = "parking_lot::Mutex" }, /// ] /// ``` /// /// ```rust,ignore @@ -51,24 +53,23 @@ declare_clippy_lint! { } pub struct DisallowedTypes { - def_ids: DefIdMap<(&'static str, Option<&'static str>)>, - prim_tys: FxHashMap<PrimTy, (&'static str, Option<&'static str>)>, + def_ids: DefIdMap<(&'static str, &'static DisallowedPath)>, + prim_tys: FxHashMap<PrimTy, (&'static str, &'static DisallowedPath)>, } impl DisallowedTypes { pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self { let mut def_ids = DefIdMap::default(); let mut prim_tys = FxHashMap::default(); - for x in &conf.disallowed_types { - let path: Vec<_> = x.path().split("::").collect::<Vec<_>>(); - let reason = x.reason(); + for disallowed_path in &conf.disallowed_types { + let path: Vec<_> = disallowed_path.path().split("::").collect::<Vec<_>>(); for res in clippy_utils::def_path_res(tcx, &path) { match res { Res::Def(_, id) => { - def_ids.insert(id, (x.path(), reason)); + def_ids.insert(id, (disallowed_path.path(), disallowed_path)); }, Res::PrimTy(ty) => { - prim_tys.insert(ty, (x.path(), reason)); + prim_tys.insert(ty, (disallowed_path.path(), disallowed_path)); }, _ => {}, } @@ -78,7 +79,7 @@ impl DisallowedTypes { } fn check_res_emit(&self, cx: &LateContext<'_>, res: &Res, span: Span) { - let (path, reason) = match res { + let (path, disallowed_path) = match res { Res::Def(_, did) if let Some(&x) = self.def_ids.get(did) => x, Res::PrimTy(prim) if let Some(&x) = self.prim_tys.get(prim) => x, _ => return, @@ -88,11 +89,7 @@ impl DisallowedTypes { DISALLOWED_TYPES, span, format!("use of a disallowed type `{path}`"), - |diag| { - if let Some(reason) = reason { - diag.note(reason); - } - }, + disallowed_path.diag_amendment(span), ); } } diff --git a/tests/ui-toml/replaceable_disallowed_types/clippy.toml b/tests/ui-toml/replaceable_disallowed_types/clippy.toml new file mode 100644 index 00000000000..a08a2f00f50 --- /dev/null +++ b/tests/ui-toml/replaceable_disallowed_types/clippy.toml @@ -0,0 +1,3 @@ +disallowed-types = [ + { path = "std::string::String", replacement = "wrapper::String" }, +] diff --git a/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.fixed b/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.fixed new file mode 100644 index 00000000000..6546981bd81 --- /dev/null +++ b/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.fixed @@ -0,0 +1,16 @@ +#![warn(clippy::disallowed_types)] + +#[allow(clippy::disallowed_types)] +mod wrapper { + pub struct String(std::string::String); + + impl From<&str> for String { + fn from(value: &str) -> Self { + Self(std::string::String::from(value)) + } + } +} + +fn main() { + let _ = wrapper::String::from("x"); +} diff --git a/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.rs b/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.rs new file mode 100644 index 00000000000..d76f1af481d --- /dev/null +++ b/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.rs @@ -0,0 +1,16 @@ +#![warn(clippy::disallowed_types)] + +#[allow(clippy::disallowed_types)] +mod wrapper { + pub struct String(std::string::String); + + impl From<&str> for String { + fn from(value: &str) -> Self { + Self(std::string::String::from(value)) + } + } +} + +fn main() { + let _ = String::from("x"); +} diff --git a/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.stderr b/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.stderr new file mode 100644 index 00000000000..bb63e6970a1 --- /dev/null +++ b/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.stderr @@ -0,0 +1,11 @@ +error: use of a disallowed type `std::string::String` + --> tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.rs:15:13 + | +LL | let _ = String::from("x"); + | ^^^^^^ help: use: `wrapper::String` + | + = note: `-D clippy::disallowed-types` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::disallowed_types)]` + +error: aborting due to 1 previous error + |
