Skip to content

Commit 2d1e9ab

Browse files
committed
Auto merge of #7345 - DevinR528:disallowed-fix, r=Manishearth
Remove requirement of fully qualified path for disallowed_method/type changelog: Remove the need for fully qualified paths in disallowed_method and disallowed_type After fixing this issue in [import_rename](rust-lang/rust-clippy#7300 (comment)) I figured I'd fix it for these two. If this does in fact fix the **Known problems:** section I was planning to remove them from both lints after confirmation.
2 parents a36a7c8 + d4eff81 commit 2d1e9ab

File tree

5 files changed

+54
-41
lines changed

5 files changed

+54
-41
lines changed

clippy_lints/src/disallowed_method.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint;
22
use clippy_utils::fn_def_id;
33

44
use rustc_data_structures::fx::FxHashSet;
5-
use rustc_hir::Expr;
5+
use rustc_hir::{def::Res, def_id::DefId, Crate, Expr};
66
use rustc_lint::{LateContext, LateLintPass};
77
use rustc_session::{declare_tool_lint, impl_lint_pass};
88
use rustc_span::Symbol;
@@ -13,21 +13,14 @@ declare_clippy_lint! {
1313
/// **Why is this bad?** Some methods are undesirable in certain contexts,
1414
/// and it's beneficial to lint for them as needed.
1515
///
16-
/// **Known problems:** Currently, you must write each function as a
17-
/// fully-qualified path. This lint doesn't support aliases or reexported
18-
/// names; be aware that many types in `std` are actually reexports.
19-
///
20-
/// For example, if you want to disallow `Duration::as_secs`, your clippy.toml
21-
/// configuration would look like
22-
/// `disallowed-methods = ["core::time::Duration::as_secs"]` and not
23-
/// `disallowed-methods = ["std::time::Duration::as_secs"]` as you might expect.
16+
/// **Known problems:** None.
2417
///
2518
/// **Example:**
2619
///
2720
/// An example clippy.toml configuration:
2821
/// ```toml
2922
/// # clippy.toml
30-
/// disallowed-methods = ["alloc::vec::Vec::leak", "std::time::Instant::now"]
23+
/// disallowed-methods = ["std::vec::Vec::leak", "std::time::Instant::now"]
3124
/// ```
3225
///
3326
/// ```rust,ignore
@@ -52,6 +45,7 @@ declare_clippy_lint! {
5245
#[derive(Clone, Debug)]
5346
pub struct DisallowedMethod {
5447
disallowed: FxHashSet<Vec<Symbol>>,
48+
def_ids: FxHashSet<(DefId, Vec<Symbol>)>,
5549
}
5650

5751
impl DisallowedMethod {
@@ -61,17 +55,28 @@ impl DisallowedMethod {
6155
.iter()
6256
.map(|s| s.split("::").map(|seg| Symbol::intern(seg)).collect::<Vec<_>>())
6357
.collect(),
58+
def_ids: FxHashSet::default(),
6459
}
6560
}
6661
}
6762

6863
impl_lint_pass!(DisallowedMethod => [DISALLOWED_METHOD]);
6964

7065
impl<'tcx> LateLintPass<'tcx> for DisallowedMethod {
66+
fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) {
67+
for path in &self.disallowed {
68+
let segs = path.iter().map(ToString::to_string).collect::<Vec<_>>();
69+
if let Res::Def(_, id) = clippy_utils::path_to_res(cx, &segs.iter().map(String::as_str).collect::<Vec<_>>())
70+
{
71+
self.def_ids.insert((id, path.clone()));
72+
}
73+
}
74+
}
75+
7176
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
7277
if let Some(def_id) = fn_def_id(cx, expr) {
73-
let func_path = cx.get_def_path(def_id);
74-
if self.disallowed.contains(&func_path) {
78+
if self.def_ids.iter().any(|(id, _)| def_id == *id) {
79+
let func_path = cx.get_def_path(def_id);
7580
let func_path_string = func_path
7681
.into_iter()
7782
.map(Symbol::to_ident_string)

clippy_lints/src/disallowed_type.rs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use clippy_utils::diagnostics::span_lint;
22

33
use rustc_data_structures::fx::FxHashSet;
4-
use rustc_hir::{def::Res, Item, ItemKind, PolyTraitRef, TraitBoundModifier, Ty, TyKind, UseKind};
4+
use rustc_hir::{
5+
def::Res, def_id::DefId, Crate, Item, ItemKind, PolyTraitRef, TraitBoundModifier, Ty, TyKind, UseKind,
6+
};
57
use rustc_lint::{LateContext, LateLintPass};
68
use rustc_session::{declare_tool_lint, impl_lint_pass};
79
use rustc_span::{Span, Symbol};
@@ -11,14 +13,7 @@ declare_clippy_lint! {
1113
///
1214
/// **Why is this bad?** Some types are undesirable in certain contexts.
1315
///
14-
/// **Known problems:** The fully qualified path must be used. This lint
15-
/// doesn't support aliases or reexported names; be aware that many types
16-
/// in `std` are actually reexports.
17-
///
18-
/// For example, if you want to disallow `BTreeMap`, your clippy.toml
19-
/// configuration would look like
20-
/// `disallowed-methods = ["alloc::collections::btree::map::BTreeMap"]` and not
21-
/// `disallowed-methods = ["std::collections::BTreeMap"]` as you might expect.
16+
/// **Known problems:** None.
2217
///
2318
/// N.B. There is no way to ban primitive types.
2419
///
@@ -27,7 +22,7 @@ declare_clippy_lint! {
2722
/// An example clippy.toml configuration:
2823
/// ```toml
2924
/// # clippy.toml
30-
/// disallowed-methods = ["alloc::collections::btree::map::BTreeMap"]
25+
/// disallowed-methods = ["std::collections::BTreeMap"]
3126
/// ```
3227
///
3328
/// ```rust,ignore
@@ -47,6 +42,7 @@ declare_clippy_lint! {
4742
#[derive(Clone, Debug)]
4843
pub struct DisallowedType {
4944
disallowed: FxHashSet<Vec<Symbol>>,
45+
def_ids: FxHashSet<(DefId, Vec<Symbol>)>,
5046
}
5147

5248
impl DisallowedType {
@@ -56,19 +52,29 @@ impl DisallowedType {
5652
.iter()
5753
.map(|s| s.split("::").map(|seg| Symbol::intern(seg)).collect::<Vec<_>>())
5854
.collect(),
55+
def_ids: FxHashSet::default(),
5956
}
6057
}
6158
}
6259

6360
impl_lint_pass!(DisallowedType => [DISALLOWED_TYPE]);
6461

6562
impl<'tcx> LateLintPass<'tcx> for DisallowedType {
63+
fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) {
64+
for path in &self.disallowed {
65+
let segs = path.iter().map(ToString::to_string).collect::<Vec<_>>();
66+
if let Res::Def(_, id) = clippy_utils::path_to_res(cx, &segs.iter().map(String::as_str).collect::<Vec<_>>())
67+
{
68+
self.def_ids.insert((id, path.clone()));
69+
}
70+
}
71+
}
72+
6673
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
6774
if_chain! {
6875
if let ItemKind::Use(path, UseKind::Single) = &item.kind;
69-
if let Res::Def(_, id) = path.res;
70-
let use_path = cx.get_def_path(id);
71-
if let Some(name) = self.disallowed.iter().find(|path| **path == use_path);
76+
if let Res::Def(_, did) = path.res;
77+
if let Some((_, name)) = self.def_ids.iter().find(|(id, _)| *id == did);
7278
then {
7379
emit(cx, name, item.span,);
7480
}
@@ -79,8 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedType {
7985
if_chain! {
8086
if let TyKind::Path(path) = &ty.kind;
8187
if let Some(did) = cx.qpath_res(path, ty.hir_id).opt_def_id();
82-
let use_path = cx.get_def_path(did);
83-
if let Some(name) = self.disallowed.iter().find(|path| **path == use_path);
88+
if let Some((_, name)) = self.def_ids.iter().find(|(id, _)| *id == did);
8489
then {
8590
emit(cx, name, path.span());
8691
}
@@ -90,8 +95,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedType {
9095
fn check_poly_trait_ref(&mut self, cx: &LateContext<'tcx>, poly: &'tcx PolyTraitRef<'tcx>, _: TraitBoundModifier) {
9196
if_chain! {
9297
if let Res::Def(_, did) = poly.trait_ref.path.res;
93-
let use_path = cx.get_def_path(did);
94-
if let Some(name) = self.disallowed.iter().find(|path| **path == use_path);
98+
if let Some((_, name)) = self.def_ids.iter().find(|(id, _)| *id == did);
9599
then {
96100
emit(cx, name, poly.trait_ref.path.span);
97101
}
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
disallowed-methods = ["core::iter::traits::iterator::Iterator::sum", "regex::re_unicode::Regex::is_match", "regex::re_unicode::Regex::new"]
1+
disallowed-methods = [
2+
"std::iter::Iterator::sum",
3+
"regex::Regex::is_match",
4+
"regex::Regex::new"
5+
]

tests/ui-toml/toml_disallowed_type/clippy.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
disallowed-types = [
2-
"std::collections::hash::map::HashMap",
3-
"core::sync::atomic::AtomicU32",
4-
"syn::ty::TypePath",
2+
"std::collections::HashMap",
3+
"std::sync::atomic::AtomicU32",
4+
"syn::TypePath",
55
"proc_macro2::Ident",
66
"std::thread::Thread",
77
"std::time::Instant",

tests/ui-toml/toml_disallowed_type/conf_disallowed_type.stderr

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: `core::sync::atomic::AtomicU32` is not allowed according to config
1+
error: `std::sync::atomic::AtomicU32` is not allowed according to config
22
--> $DIR/conf_disallowed_type.rs:7:1
33
|
44
LL | use std::sync::atomic::AtomicU32;
@@ -24,7 +24,7 @@ error: `std::time::Instant` is not allowed according to config
2424
LL | fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) {
2525
| ^^^^^^
2626

27-
error: `core::sync::atomic::AtomicU32` is not allowed according to config
27+
error: `std::sync::atomic::AtomicU32` is not allowed according to config
2828
--> $DIR/conf_disallowed_type.rs:16:39
2929
|
3030
LL | fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) {
@@ -36,13 +36,13 @@ error: `std::io::Read` is not allowed according to config
3636
LL | fn trait_obj(_: &dyn std::io::Read) {
3737
| ^^^^^^^^^^^^^
3838

39-
error: `std::collections::hash::map::HashMap` is not allowed according to config
39+
error: `std::collections::HashMap` is not allowed according to config
4040
--> $DIR/conf_disallowed_type.rs:28:48
4141
|
4242
LL | let _: std::collections::HashMap<(), ()> = std::collections::HashMap::new();
4343
| ^^^^^^^^^^^^^^^^^^^^^^^^^
4444

45-
error: `std::collections::hash::map::HashMap` is not allowed according to config
45+
error: `std::collections::HashMap` is not allowed according to config
4646
--> $DIR/conf_disallowed_type.rs:28:12
4747
|
4848
LL | let _: std::collections::HashMap<(), ()> = std::collections::HashMap::new();
@@ -54,25 +54,25 @@ error: `std::time::Instant` is not allowed according to config
5454
LL | let _ = Sneaky::now();
5555
| ^^^^^^
5656

57-
error: `core::sync::atomic::AtomicU32` is not allowed according to config
57+
error: `std::sync::atomic::AtomicU32` is not allowed according to config
5858
--> $DIR/conf_disallowed_type.rs:30:13
5959
|
6060
LL | let _ = foo::atomic::AtomicU32::new(0);
6161
| ^^^^^^^^^^^^^^^^^^^^^^
6262

63-
error: `core::sync::atomic::AtomicU32` is not allowed according to config
63+
error: `std::sync::atomic::AtomicU32` is not allowed according to config
6464
--> $DIR/conf_disallowed_type.rs:31:17
6565
|
6666
LL | static FOO: std::sync::atomic::AtomicU32 = foo::atomic::AtomicU32::new(1);
6767
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6868

69-
error: `core::sync::atomic::AtomicU32` is not allowed according to config
69+
error: `std::sync::atomic::AtomicU32` is not allowed according to config
7070
--> $DIR/conf_disallowed_type.rs:31:48
7171
|
7272
LL | static FOO: std::sync::atomic::AtomicU32 = foo::atomic::AtomicU32::new(1);
7373
| ^^^^^^^^^^^^^^^^^^^^^^
7474

75-
error: `syn::ty::TypePath` is not allowed according to config
75+
error: `syn::TypePath` is not allowed according to config
7676
--> $DIR/conf_disallowed_type.rs:32:43
7777
|
7878
LL | let _: std::collections::BTreeMap<(), syn::TypePath> = Default::default();

0 commit comments

Comments
 (0)