Skip to content

Commit

Permalink
Add conf to disable disallowed_types in macros
Browse files Browse the repository at this point in the history
  • Loading branch information
stepantubanov committed Jun 21, 2024
1 parent 0ce07f6 commit 73b0639
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 23 deletions.
4 changes: 4 additions & 0 deletions clippy_config/src/conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,10 @@ define_Conf! {
///
/// The list of disallowed types, written as fully qualified paths.
(disallowed_types: Vec<DisallowedPath> = Vec::new()),
/// Lint: DISALLOWED_TYPES.
///
/// Enables lint in external macros.
(lint_disallowed_types_in_external_macros: bool = true),
/// Lint: UNREADABLE_LITERAL.
///
/// Should the fraction of a decimal be linted to include separators.
Expand Down
22 changes: 21 additions & 1 deletion clippy_lints/src/disallowed_types.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use crate::rustc_lint::LintContext;
use clippy_config::types::DisallowedPath;
use clippy_utils::diagnostics::span_lint_and_then;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def::Res;
use rustc_hir::def_id::DefId;
use rustc_hir::{Item, ItemKind, PolyTraitRef, PrimTy, Ty, TyKind, UseKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
use rustc_span::Span;

Expand Down Expand Up @@ -52,14 +54,16 @@ declare_clippy_lint! {
#[derive(Clone, Debug)]
pub struct DisallowedTypes {
conf_disallowed: Vec<DisallowedPath>,
conf_lint_external_macros: bool,
def_ids: FxHashMap<DefId, usize>,
prim_tys: FxHashMap<PrimTy, usize>,
}

impl DisallowedTypes {
pub fn new(conf_disallowed: Vec<DisallowedPath>) -> Self {
pub fn new(conf_disallowed: Vec<DisallowedPath>, conf_lint_external_macros: bool) -> Self {
Self {
conf_disallowed,
conf_lint_external_macros,
def_ids: FxHashMap::default(),
prim_tys: FxHashMap::default(),
}
Expand Down Expand Up @@ -105,6 +109,12 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {

fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
if let ItemKind::Use(path, UseKind::Single) = &item.kind {
if !self.conf_lint_external_macros
&& (in_external_macro(cx.sess(), item.span) || clippy_utils::is_from_proc_macro(cx, item))
{
return;
}

for res in &path.res {
self.check_res_emit(cx, res, item.span);
}
Expand All @@ -113,11 +123,21 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {

fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) {
if let TyKind::Path(path) = &ty.kind {
if !self.conf_lint_external_macros
&& (in_external_macro(cx.sess(), ty.span) || clippy_utils::is_from_proc_macro(cx, ty))
{
return;
}

self.check_res_emit(cx, &cx.qpath_res(path, ty.hir_id), ty.span);
}
}

fn check_poly_trait_ref(&mut self, cx: &LateContext<'tcx>, poly: &'tcx PolyTraitRef<'tcx>) {
if !self.conf_lint_external_macros && in_external_macro(cx.sess(), poly.span) {
return;
}

self.check_res_emit(cx, &poly.trait_ref.path.res, poly.trait_ref.path.span);
}
}
Expand Down
8 changes: 7 additions & 1 deletion clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
ref disallowed_methods,
ref disallowed_names,
ref disallowed_types,
lint_disallowed_types_in_external_macros,
ref doc_valid_idents,
enable_raw_pointer_heuristic_for_send,
enforce_iter_loop_reborrow,
Expand Down Expand Up @@ -958,7 +959,12 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
store.register_late_pass(|_| Box::new(bool_assert_comparison::BoolAssertComparison));
store.register_early_pass(move || Box::new(module_style::ModStyle));
store.register_late_pass(|_| Box::<unused_async::UnusedAsync>::default());
store.register_late_pass(move |_| Box::new(disallowed_types::DisallowedTypes::new(disallowed_types.clone())));
store.register_late_pass(move |_| {
Box::new(disallowed_types::DisallowedTypes::new(
disallowed_types.clone(),
lint_disallowed_types_in_external_macros,
))
});
store.register_late_pass(move |_| {
Box::new(missing_enforced_import_rename::ImportRename::new(
enforced_import_renames.clone(),
Expand Down
18 changes: 18 additions & 0 deletions tests/ui-toml/toml_disallowed_types/auxiliary/proc_macro_attr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
extern crate proc_macro;
extern crate quote;

use proc_macro::TokenStream;
use quote::quote;

#[proc_macro_attribute]
pub fn use_std_hash_map(_args: TokenStream, input: TokenStream) -> TokenStream {
TokenStream::from_iter([
input,
quote!(
pub fn new_function() {
let _ = std::collections::HashMap::<i32, i32>::default();
}
)
.into(),
])
}
1 change: 1 addition & 0 deletions tests/ui-toml/toml_disallowed_types/clippy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ disallowed-types = [
# can use an inline table but omit reason
{ path = "std::net::TcpListener" },
]
lint-disallowed-types-in-external-macros = false
6 changes: 6 additions & 0 deletions tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//@aux-build:proc_macro_attr.rs
#![warn(clippy::disallowed_types)]

extern crate proc_macro_attr;
extern crate quote;
extern crate syn;

Expand Down Expand Up @@ -39,6 +41,10 @@ fn main() {
let _ = syn::Ident::new("", todo!());
let _ = HashMap;
let _: usize = 64_usize;

// Lint should not report usage of std::collections::HashMap inside a foreign macro
#[proc_macro_attr::use_std_hash_map]
fn _foo() {}
}

mod useless_attribute {
Expand Down
42 changes: 21 additions & 21 deletions tests/ui-toml/toml_disallowed_types/conf_disallowed_types.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: `std::sync::atomic::AtomicU32` is not allowed according to config
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:7:1
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:9:1
|
LL | use std::sync::atomic::AtomicU32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -8,123 +8,123 @@ LL | use std::sync::atomic::AtomicU32;
= help: to override `-D warnings` add `#[allow(clippy::disallowed_types)]`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

0 comments on commit 73b0639

Please sign in to comment.