Skip to content

Commit 73b0639

Browse files
committed
Add conf to disable disallowed_types in macros
1 parent 0ce07f6 commit 73b0639

File tree

7 files changed

+78
-23
lines changed

7 files changed

+78
-23
lines changed

clippy_config/src/conf.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@ define_Conf! {
400400
///
401401
/// The list of disallowed types, written as fully qualified paths.
402402
(disallowed_types: Vec<DisallowedPath> = Vec::new()),
403+
/// Lint: DISALLOWED_TYPES.
404+
///
405+
/// Enables lint in external macros.
406+
(lint_disallowed_types_in_external_macros: bool = true),
403407
/// Lint: UNREADABLE_LITERAL.
404408
///
405409
/// Should the fraction of a decimal be linted to include separators.

clippy_lints/src/disallowed_types.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
use crate::rustc_lint::LintContext;
12
use clippy_config::types::DisallowedPath;
23
use clippy_utils::diagnostics::span_lint_and_then;
34
use rustc_data_structures::fx::FxHashMap;
45
use rustc_hir::def::Res;
56
use rustc_hir::def_id::DefId;
67
use rustc_hir::{Item, ItemKind, PolyTraitRef, PrimTy, Ty, TyKind, UseKind};
78
use rustc_lint::{LateContext, LateLintPass};
9+
use rustc_middle::lint::in_external_macro;
810
use rustc_session::impl_lint_pass;
911
use rustc_span::Span;
1012

@@ -52,14 +54,16 @@ declare_clippy_lint! {
5254
#[derive(Clone, Debug)]
5355
pub struct DisallowedTypes {
5456
conf_disallowed: Vec<DisallowedPath>,
57+
conf_lint_external_macros: bool,
5558
def_ids: FxHashMap<DefId, usize>,
5659
prim_tys: FxHashMap<PrimTy, usize>,
5760
}
5861

5962
impl DisallowedTypes {
60-
pub fn new(conf_disallowed: Vec<DisallowedPath>) -> Self {
63+
pub fn new(conf_disallowed: Vec<DisallowedPath>, conf_lint_external_macros: bool) -> Self {
6164
Self {
6265
conf_disallowed,
66+
conf_lint_external_macros,
6367
def_ids: FxHashMap::default(),
6468
prim_tys: FxHashMap::default(),
6569
}
@@ -105,6 +109,12 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {
105109

106110
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
107111
if let ItemKind::Use(path, UseKind::Single) = &item.kind {
112+
if !self.conf_lint_external_macros
113+
&& (in_external_macro(cx.sess(), item.span) || clippy_utils::is_from_proc_macro(cx, item))
114+
{
115+
return;
116+
}
117+
108118
for res in &path.res {
109119
self.check_res_emit(cx, res, item.span);
110120
}
@@ -113,11 +123,21 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {
113123

114124
fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) {
115125
if let TyKind::Path(path) = &ty.kind {
126+
if !self.conf_lint_external_macros
127+
&& (in_external_macro(cx.sess(), ty.span) || clippy_utils::is_from_proc_macro(cx, ty))
128+
{
129+
return;
130+
}
131+
116132
self.check_res_emit(cx, &cx.qpath_res(path, ty.hir_id), ty.span);
117133
}
118134
}
119135

120136
fn check_poly_trait_ref(&mut self, cx: &LateContext<'tcx>, poly: &'tcx PolyTraitRef<'tcx>) {
137+
if !self.conf_lint_external_macros && in_external_macro(cx.sess(), poly.span) {
138+
return;
139+
}
140+
121141
self.check_res_emit(cx, &poly.trait_ref.path.res, poly.trait_ref.path.span);
122142
}
123143
}

clippy_lints/src/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
557557
ref disallowed_methods,
558558
ref disallowed_names,
559559
ref disallowed_types,
560+
lint_disallowed_types_in_external_macros,
560561
ref doc_valid_idents,
561562
enable_raw_pointer_heuristic_for_send,
562563
enforce_iter_loop_reborrow,
@@ -958,7 +959,12 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
958959
store.register_late_pass(|_| Box::new(bool_assert_comparison::BoolAssertComparison));
959960
store.register_early_pass(move || Box::new(module_style::ModStyle));
960961
store.register_late_pass(|_| Box::<unused_async::UnusedAsync>::default());
961-
store.register_late_pass(move |_| Box::new(disallowed_types::DisallowedTypes::new(disallowed_types.clone())));
962+
store.register_late_pass(move |_| {
963+
Box::new(disallowed_types::DisallowedTypes::new(
964+
disallowed_types.clone(),
965+
lint_disallowed_types_in_external_macros,
966+
))
967+
});
962968
store.register_late_pass(move |_| {
963969
Box::new(missing_enforced_import_rename::ImportRename::new(
964970
enforced_import_renames.clone(),
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
extern crate proc_macro;
2+
extern crate quote;
3+
4+
use proc_macro::TokenStream;
5+
use quote::quote;
6+
7+
#[proc_macro_attribute]
8+
pub fn use_std_hash_map(_args: TokenStream, input: TokenStream) -> TokenStream {
9+
TokenStream::from_iter([
10+
input,
11+
quote!(
12+
pub fn new_function() {
13+
let _ = std::collections::HashMap::<i32, i32>::default();
14+
}
15+
)
16+
.into(),
17+
])
18+
}

tests/ui-toml/toml_disallowed_types/clippy.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ disallowed-types = [
1313
# can use an inline table but omit reason
1414
{ path = "std::net::TcpListener" },
1515
]
16+
lint-disallowed-types-in-external-macros = false

tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
//@aux-build:proc_macro_attr.rs
12
#![warn(clippy::disallowed_types)]
23

4+
extern crate proc_macro_attr;
35
extern crate quote;
46
extern crate syn;
57

@@ -39,6 +41,10 @@ fn main() {
3941
let _ = syn::Ident::new("", todo!());
4042
let _ = HashMap;
4143
let _: usize = 64_usize;
44+
45+
// Lint should not report usage of std::collections::HashMap inside a foreign macro
46+
#[proc_macro_attr::use_std_hash_map]
47+
fn _foo() {}
4248
}
4349

4450
mod useless_attribute {

tests/ui-toml/toml_disallowed_types/conf_disallowed_types.stderr

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: `std::sync::atomic::AtomicU32` is not allowed according to config
2-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:7:1
2+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:9:1
33
|
44
LL | use std::sync::atomic::AtomicU32;
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,123 +8,123 @@ LL | use std::sync::atomic::AtomicU32;
88
= help: to override `-D warnings` add `#[allow(clippy::disallowed_types)]`
99

1010
error: `std::time::Instant` is not allowed according to config
11-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:8:1
11+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:10:1
1212
|
1313
LL | use std::time::Instant as Sneaky;
1414
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1515

1616
error: `std::time::Instant` is not allowed according to config
17-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:12:33
17+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:14:33
1818
|
1919
LL | fn bad_return_type() -> fn() -> Sneaky {
2020
| ^^^^^^
2121

2222
error: `std::time::Instant` is not allowed according to config
23-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:16:28
23+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:18:28
2424
|
2525
LL | fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) {}
2626
| ^^^^^^
2727

2828
error: `std::sync::atomic::AtomicU32` is not allowed according to config
29-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:16:39
29+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:18:39
3030
|
3131
LL | fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) {}
3232
| ^^^^^^^^^^^^^^^^^^^^^^
3333

3434
error: `std::io::Read` is not allowed according to config
35-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:18:22
35+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:20:22
3636
|
3737
LL | fn trait_obj(_: &dyn std::io::Read) {}
3838
| ^^^^^^^^^^^^^
3939

4040
error: `usize` is not allowed according to config
41-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:20:33
41+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:22:33
4242
|
4343
LL | fn full_and_single_path_prim(_: usize, _: bool) {}
4444
| ^^^^^
4545

4646
error: `bool` is not allowed according to config
47-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:20:43
47+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:22:43
4848
|
4949
LL | fn full_and_single_path_prim(_: usize, _: bool) {}
5050
| ^^^^
5151

5252
error: `usize` is not allowed according to config
53-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:22:28
53+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:24:28
5454
|
5555
LL | fn const_generics<const C: usize>() {}
5656
| ^^^^^
5757

5858
error: `usize` is not allowed according to config
59-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:24:24
59+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:26:24
6060
|
6161
LL | struct GenArg<const U: usize>([u8; U]);
6262
| ^^^^^
6363

6464
error: `std::net::Ipv4Addr` is not allowed according to config
65-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:28:10
65+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:30:10
6666
|
6767
LL | fn ip(_: std::net::Ipv4Addr) {}
6868
| ^^^^^^^^^^^^^^^^^^
6969
|
7070
= note: no IPv4 allowed (from clippy.toml)
7171

7272
error: `std::net::TcpListener` is not allowed according to config
73-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:30:16
73+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:32:16
7474
|
7575
LL | fn listener(_: std::net::TcpListener) {}
7676
| ^^^^^^^^^^^^^^^^^^^^^
7777

7878
error: `std::collections::HashMap` is not allowed according to config
79-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:34:48
79+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:36:48
8080
|
8181
LL | let _: std::collections::HashMap<(), ()> = std::collections::HashMap::new();
8282
| ^^^^^^^^^^^^^^^^^^^^^^^^^
8383

8484
error: `std::collections::HashMap` is not allowed according to config
85-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:34:12
85+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:36:12
8686
|
8787
LL | let _: std::collections::HashMap<(), ()> = std::collections::HashMap::new();
8888
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8989

9090
error: `std::time::Instant` is not allowed according to config
91-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:35:13
91+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:37:13
9292
|
9393
LL | let _ = Sneaky::now();
9494
| ^^^^^^
9595

9696
error: `std::sync::atomic::AtomicU32` is not allowed according to config
97-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:36:13
97+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:38:13
9898
|
9999
LL | let _ = foo::atomic::AtomicU32::new(0);
100100
| ^^^^^^^^^^^^^^^^^^^^^^
101101

102102
error: `std::sync::atomic::AtomicU32` is not allowed according to config
103-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:37:17
103+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:39:17
104104
|
105105
LL | static FOO: std::sync::atomic::AtomicU32 = foo::atomic::AtomicU32::new(1);
106106
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
107107

108108
error: `std::sync::atomic::AtomicU32` is not allowed according to config
109-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:37:48
109+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:39:48
110110
|
111111
LL | static FOO: std::sync::atomic::AtomicU32 = foo::atomic::AtomicU32::new(1);
112112
| ^^^^^^^^^^^^^^^^^^^^^^
113113

114114
error: `syn::TypePath` is not allowed according to config
115-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:38:43
115+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:40:43
116116
|
117117
LL | let _: std::collections::BTreeMap<(), syn::TypePath> = Default::default();
118118
| ^^^^^^^^^^^^^
119119

120120
error: `syn::Ident` is not allowed according to config
121-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:39:13
121+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:41:13
122122
|
123123
LL | let _ = syn::Ident::new("", todo!());
124124
| ^^^^^^^^^^
125125

126126
error: `usize` is not allowed according to config
127-
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:41:12
127+
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:43:12
128128
|
129129
LL | let _: usize = 64_usize;
130130
| ^^^^^

0 commit comments

Comments
 (0)