Properly handle disallowed_types
This commit is contained in:
parent
f159a3eb1d
commit
d0f3577720
6 changed files with 58 additions and 15 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
3
tests/ui-toml/replaceable_disallowed_types/clippy.toml
Normal file
3
tests/ui-toml/replaceable_disallowed_types/clippy.toml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
disallowed-types = [
|
||||
{ path = "std::string::String", replacement = "wrapper::String" },
|
||||
]
|
||||
|
|
@ -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");
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue