mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-27 15:11:30 +00:00
Add disallowed_macros
lint
This commit is contained in:
parent
425e1ea73d
commit
86c86c3742
23 changed files with 500 additions and 110 deletions
|
@ -3820,6 +3820,7 @@ Released 2018-09-13
|
|||
[`derive_hash_xor_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_hash_xor_eq
|
||||
[`derive_ord_xor_partial_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_ord_xor_partial_ord
|
||||
[`derive_partial_eq_without_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
|
||||
[`disallowed_macros`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_macros
|
||||
[`disallowed_method`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_method
|
||||
[`disallowed_methods`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_methods
|
||||
[`disallowed_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::{match_def_path, paths};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir::def::{Namespace, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{def::Res, AsyncGeneratorKind, Body, BodyId, GeneratorKind};
|
||||
use rustc_hir::{AsyncGeneratorKind, Body, BodyId, GeneratorKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::GeneratorInteriorTypeCause;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::{sym, Span};
|
||||
|
||||
use crate::utils::conf::DisallowedType;
|
||||
use crate::utils::conf::DisallowedPath;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
|
@ -171,12 +172,12 @@ impl_lint_pass!(AwaitHolding => [AWAIT_HOLDING_LOCK, AWAIT_HOLDING_REFCELL_REF,
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct AwaitHolding {
|
||||
conf_invalid_types: Vec<DisallowedType>,
|
||||
def_ids: FxHashMap<DefId, DisallowedType>,
|
||||
conf_invalid_types: Vec<DisallowedPath>,
|
||||
def_ids: FxHashMap<DefId, DisallowedPath>,
|
||||
}
|
||||
|
||||
impl AwaitHolding {
|
||||
pub(crate) fn new(conf_invalid_types: Vec<DisallowedType>) -> Self {
|
||||
pub(crate) fn new(conf_invalid_types: Vec<DisallowedPath>) -> Self {
|
||||
Self {
|
||||
conf_invalid_types,
|
||||
def_ids: FxHashMap::default(),
|
||||
|
@ -187,11 +188,8 @@ impl AwaitHolding {
|
|||
impl LateLintPass<'_> for AwaitHolding {
|
||||
fn check_crate(&mut self, cx: &LateContext<'_>) {
|
||||
for conf in &self.conf_invalid_types {
|
||||
let path = match conf {
|
||||
DisallowedType::Simple(path) | DisallowedType::WithReason { path, .. } => path,
|
||||
};
|
||||
let segs: Vec<_> = path.split("::").collect();
|
||||
if let Res::Def(_, id) = clippy_utils::def_path_res(cx, &segs) {
|
||||
let segs: Vec<_> = conf.path().split("::").collect();
|
||||
if let Res::Def(_, id) = clippy_utils::def_path_res(cx, &segs, Some(Namespace::TypeNS)) {
|
||||
self.def_ids.insert(id, conf.clone());
|
||||
}
|
||||
}
|
||||
|
@ -256,20 +254,18 @@ impl AwaitHolding {
|
|||
}
|
||||
}
|
||||
|
||||
fn emit_invalid_type(cx: &LateContext<'_>, span: Span, disallowed: &DisallowedType) {
|
||||
let (type_name, reason) = match disallowed {
|
||||
DisallowedType::Simple(path) => (path, &None),
|
||||
DisallowedType::WithReason { path, reason } => (path, reason),
|
||||
};
|
||||
|
||||
fn emit_invalid_type(cx: &LateContext<'_>, span: Span, disallowed: &DisallowedPath) {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
AWAIT_HOLDING_INVALID_TYPE,
|
||||
span,
|
||||
&format!("`{type_name}` may not be held across an `await` point per `clippy.toml`",),
|
||||
&format!(
|
||||
"`{}` may not be held across an `await` point per `clippy.toml`",
|
||||
disallowed.path()
|
||||
),
|
||||
|diag| {
|
||||
if let Some(reason) = reason {
|
||||
diag.note(reason.clone());
|
||||
if let Some(reason) = disallowed.reason() {
|
||||
diag.note(reason);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
151
clippy_lints/src/disallowed_macros.rs
Normal file
151
clippy_lints/src/disallowed_macros.rs
Normal file
|
@ -0,0 +1,151 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::macros::macro_backtrace;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir::def::{Namespace, Res};
|
||||
use rustc_hir::def_id::DefIdMap;
|
||||
use rustc_hir::{Expr, ForeignItem, HirId, ImplItem, Item, Pat, Path, Stmt, TraitItem, Ty};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::{ExpnId, Span};
|
||||
|
||||
use crate::utils::conf;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Denies the configured macros in clippy.toml
|
||||
///
|
||||
/// Note: Even though this lint is warn-by-default, it will only trigger if
|
||||
/// macros are defined in the clippy.toml file.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// Some macros are undesirable in certain contexts, and it's beneficial to
|
||||
/// lint for them as needed.
|
||||
///
|
||||
/// ### Example
|
||||
/// An example clippy.toml configuration:
|
||||
/// ```toml
|
||||
/// # clippy.toml
|
||||
/// disallowed-macros = [
|
||||
/// # Can use a string as the path of the disallowed macro.
|
||||
/// "std::print",
|
||||
/// # Can also use an inline table with a `path` key.
|
||||
/// { path = "std::println" },
|
||||
/// # When using an inline table, can add a `reason` for why the macro
|
||||
/// # is disallowed.
|
||||
/// { path = "serde::Serialize", reason = "no serializing" },
|
||||
/// ]
|
||||
/// ```
|
||||
/// ```
|
||||
/// use serde::Serialize;
|
||||
///
|
||||
/// // Example code where clippy issues a warning
|
||||
/// println!("warns");
|
||||
///
|
||||
/// // The diagnostic will contain the message "no serializing"
|
||||
/// #[derive(Serialize)]
|
||||
/// struct Data {
|
||||
/// name: String,
|
||||
/// value: usize,
|
||||
/// }
|
||||
/// ```
|
||||
#[clippy::version = "1.65.0"]
|
||||
pub DISALLOWED_MACROS,
|
||||
style,
|
||||
"use of a disallowed macro"
|
||||
}
|
||||
|
||||
pub struct DisallowedMacros {
|
||||
conf_disallowed: Vec<conf::DisallowedPath>,
|
||||
disallowed: DefIdMap<usize>,
|
||||
seen: FxHashSet<ExpnId>,
|
||||
}
|
||||
|
||||
impl DisallowedMacros {
|
||||
pub fn new(conf_disallowed: Vec<conf::DisallowedPath>) -> Self {
|
||||
Self {
|
||||
conf_disallowed,
|
||||
disallowed: DefIdMap::default(),
|
||||
seen: FxHashSet::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn check(&mut self, cx: &LateContext<'_>, span: Span) {
|
||||
if self.conf_disallowed.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
for mac in macro_backtrace(span) {
|
||||
if !self.seen.insert(mac.expn) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(&index) = self.disallowed.get(&mac.def_id) {
|
||||
let conf = &self.conf_disallowed[index];
|
||||
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
DISALLOWED_MACROS,
|
||||
mac.span,
|
||||
&format!("use of a disallowed macro `{}`", conf.path()),
|
||||
|diag| {
|
||||
if let Some(reason) = conf.reason() {
|
||||
diag.note(&format!("{reason} (from clippy.toml)"));
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_lint_pass!(DisallowedMacros => [DISALLOWED_MACROS]);
|
||||
|
||||
impl LateLintPass<'_> for DisallowedMacros {
|
||||
fn check_crate(&mut self, cx: &LateContext<'_>) {
|
||||
for (index, conf) in self.conf_disallowed.iter().enumerate() {
|
||||
let segs: Vec<_> = conf.path().split("::").collect();
|
||||
if let Res::Def(_, id) = clippy_utils::def_path_res(cx, &segs, Some(Namespace::MacroNS)) {
|
||||
self.disallowed.insert(id, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
self.check(cx, expr.span);
|
||||
}
|
||||
|
||||
fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) {
|
||||
self.check(cx, stmt.span);
|
||||
}
|
||||
|
||||
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &Ty<'_>) {
|
||||
self.check(cx, ty.span);
|
||||
}
|
||||
|
||||
fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) {
|
||||
self.check(cx, pat.span);
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
|
||||
self.check(cx, item.span);
|
||||
self.check(cx, item.vis_span);
|
||||
}
|
||||
|
||||
fn check_foreign_item(&mut self, cx: &LateContext<'_>, item: &ForeignItem<'_>) {
|
||||
self.check(cx, item.span);
|
||||
self.check(cx, item.vis_span);
|
||||
}
|
||||
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &ImplItem<'_>) {
|
||||
self.check(cx, item.span);
|
||||
self.check(cx, item.vis_span);
|
||||
}
|
||||
|
||||
fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &TraitItem<'_>) {
|
||||
self.check(cx, item.span);
|
||||
}
|
||||
|
||||
fn check_path(&mut self, cx: &LateContext<'_>, path: &Path<'_>, _: HirId) {
|
||||
self.check(cx, path.span);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::{fn_def_id, get_parent_expr, path_def_id};
|
||||
|
||||
use rustc_hir::{def::Res, def_id::DefIdMap, Expr, ExprKind};
|
||||
use rustc_hir::def::{Namespace, Res};
|
||||
use rustc_hir::def_id::DefIdMap;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
||||
|
@ -58,12 +60,12 @@ declare_clippy_lint! {
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DisallowedMethods {
|
||||
conf_disallowed: Vec<conf::DisallowedMethod>,
|
||||
conf_disallowed: Vec<conf::DisallowedPath>,
|
||||
disallowed: DefIdMap<usize>,
|
||||
}
|
||||
|
||||
impl DisallowedMethods {
|
||||
pub fn new(conf_disallowed: Vec<conf::DisallowedMethod>) -> Self {
|
||||
pub fn new(conf_disallowed: Vec<conf::DisallowedPath>) -> Self {
|
||||
Self {
|
||||
conf_disallowed,
|
||||
disallowed: DefIdMap::default(),
|
||||
|
@ -77,7 +79,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedMethods {
|
|||
fn check_crate(&mut self, cx: &LateContext<'_>) {
|
||||
for (index, conf) in self.conf_disallowed.iter().enumerate() {
|
||||
let segs: Vec<_> = conf.path().split("::").collect();
|
||||
if let Res::Def(_, id) = clippy_utils::def_path_res(cx, &segs) {
|
||||
if let Res::Def(_, id) = clippy_utils::def_path_res(cx, &segs, Some(Namespace::ValueNS)) {
|
||||
self.disallowed.insert(id, index);
|
||||
}
|
||||
}
|
||||
|
@ -102,10 +104,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedMethods {
|
|||
};
|
||||
let msg = format!("use of a disallowed method `{}`", conf.path());
|
||||
span_lint_and_then(cx, DISALLOWED_METHODS, expr.span, &msg, |diag| {
|
||||
if let conf::DisallowedMethod::WithReason {
|
||||
reason: Some(reason), ..
|
||||
} = conf
|
||||
{
|
||||
if let Some(reason) = conf.reason() {
|
||||
diag.note(&format!("{reason} (from clippy.toml)"));
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir::{def::Res, def_id::DefId, Item, ItemKind, PolyTraitRef, PrimTy, Ty, TyKind, UseKind};
|
||||
use rustc_hir::def::{Namespace, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{Item, ItemKind, PolyTraitRef, PrimTy, Ty, TyKind, UseKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::Span;
|
||||
|
@ -50,13 +52,13 @@ declare_clippy_lint! {
|
|||
}
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DisallowedTypes {
|
||||
conf_disallowed: Vec<conf::DisallowedType>,
|
||||
conf_disallowed: Vec<conf::DisallowedPath>,
|
||||
def_ids: FxHashMap<DefId, Option<String>>,
|
||||
prim_tys: FxHashMap<PrimTy, Option<String>>,
|
||||
}
|
||||
|
||||
impl DisallowedTypes {
|
||||
pub fn new(conf_disallowed: Vec<conf::DisallowedType>) -> Self {
|
||||
pub fn new(conf_disallowed: Vec<conf::DisallowedPath>) -> Self {
|
||||
Self {
|
||||
conf_disallowed,
|
||||
def_ids: FxHashMap::default(),
|
||||
|
@ -86,15 +88,9 @@ impl_lint_pass!(DisallowedTypes => [DISALLOWED_TYPES]);
|
|||
impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {
|
||||
fn check_crate(&mut self, cx: &LateContext<'_>) {
|
||||
for conf in &self.conf_disallowed {
|
||||
let (path, reason) = match conf {
|
||||
conf::DisallowedType::Simple(path) => (path, None),
|
||||
conf::DisallowedType::WithReason { path, reason } => (
|
||||
path,
|
||||
reason.as_ref().map(|reason| format!("{reason} (from clippy.toml)")),
|
||||
),
|
||||
};
|
||||
let segs: Vec<_> = path.split("::").collect();
|
||||
match clippy_utils::def_path_res(cx, &segs) {
|
||||
let segs: Vec<_> = conf.path().split("::").collect();
|
||||
let reason = conf.reason().map(|reason| format!("{reason} (from clippy.toml)"));
|
||||
match clippy_utils::def_path_res(cx, &segs, Some(Namespace::TypeNS)) {
|
||||
Res::Def(_, id) => {
|
||||
self.def_ids.insert(id, reason);
|
||||
},
|
||||
|
|
|
@ -45,6 +45,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
|
|||
LintId::of(derivable_impls::DERIVABLE_IMPLS),
|
||||
LintId::of(derive::DERIVE_HASH_XOR_EQ),
|
||||
LintId::of(derive::DERIVE_ORD_XOR_PARTIAL_ORD),
|
||||
LintId::of(disallowed_macros::DISALLOWED_MACROS),
|
||||
LintId::of(disallowed_methods::DISALLOWED_METHODS),
|
||||
LintId::of(disallowed_names::DISALLOWED_NAMES),
|
||||
LintId::of(disallowed_types::DISALLOWED_TYPES),
|
||||
|
|
|
@ -114,6 +114,7 @@ store.register_lints(&[
|
|||
derive::DERIVE_PARTIAL_EQ_WITHOUT_EQ,
|
||||
derive::EXPL_IMPL_CLONE_ON_COPY,
|
||||
derive::UNSAFE_DERIVE_DESERIALIZE,
|
||||
disallowed_macros::DISALLOWED_MACROS,
|
||||
disallowed_methods::DISALLOWED_METHODS,
|
||||
disallowed_names::DISALLOWED_NAMES,
|
||||
disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS,
|
||||
|
|
|
@ -15,6 +15,7 @@ store.register_group(true, "clippy::style", Some("clippy_style"), vec![
|
|||
LintId::of(default::FIELD_REASSIGN_WITH_DEFAULT),
|
||||
LintId::of(default_instead_of_iter_empty::DEFAULT_INSTEAD_OF_ITER_EMPTY),
|
||||
LintId::of(dereference::NEEDLESS_BORROW),
|
||||
LintId::of(disallowed_macros::DISALLOWED_MACROS),
|
||||
LintId::of(disallowed_methods::DISALLOWED_METHODS),
|
||||
LintId::of(disallowed_names::DISALLOWED_NAMES),
|
||||
LintId::of(disallowed_types::DISALLOWED_TYPES),
|
||||
|
|
|
@ -199,6 +199,7 @@ mod default_union_representation;
|
|||
mod dereference;
|
||||
mod derivable_impls;
|
||||
mod derive;
|
||||
mod disallowed_macros;
|
||||
mod disallowed_methods;
|
||||
mod disallowed_names;
|
||||
mod disallowed_script_idents;
|
||||
|
@ -820,6 +821,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
store.register_late_pass(|_| Box::new(unwrap_in_result::UnwrapInResult));
|
||||
store.register_late_pass(|_| Box::new(semicolon_if_nothing_returned::SemicolonIfNothingReturned));
|
||||
store.register_late_pass(|_| Box::new(async_yields_async::AsyncYieldsAsync));
|
||||
let disallowed_macros = conf.disallowed_macros.clone();
|
||||
store.register_late_pass(move |_| Box::new(disallowed_macros::DisallowedMacros::new(disallowed_macros.clone())));
|
||||
let disallowed_methods = conf.disallowed_methods.clone();
|
||||
store.register_late_pass(move |_| Box::new(disallowed_methods::DisallowedMethods::new(disallowed_methods.clone())));
|
||||
store.register_early_pass(|| Box::new(asm_syntax::InlineAsmX86AttSyntax));
|
||||
|
|
|
@ -58,7 +58,8 @@ impl_lint_pass!(ImportRename => [MISSING_ENFORCED_IMPORT_RENAMES]);
|
|||
impl LateLintPass<'_> for ImportRename {
|
||||
fn check_crate(&mut self, cx: &LateContext<'_>) {
|
||||
for Rename { path, rename } in &self.conf_renames {
|
||||
if let Res::Def(_, id) = clippy_utils::def_path_res(cx, &path.split("::").collect::<Vec<_>>()) {
|
||||
let segs = path.split("::").collect::<Vec<_>>();
|
||||
if let Res::Def(_, id) = clippy_utils::def_path_res(cx, &segs, None) {
|
||||
self.renames.insert(id, Symbol::intern(rename));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,28 +39,28 @@ pub struct Rename {
|
|||
pub rename: String,
|
||||
}
|
||||
|
||||
/// A single disallowed method, used by the `DISALLOWED_METHODS` lint.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum DisallowedMethod {
|
||||
pub enum DisallowedPath {
|
||||
Simple(String),
|
||||
WithReason { path: String, reason: Option<String> },
|
||||
}
|
||||
|
||||
impl DisallowedMethod {
|
||||
impl DisallowedPath {
|
||||
pub fn path(&self) -> &str {
|
||||
let (Self::Simple(path) | Self::WithReason { path, .. }) = self;
|
||||
|
||||
path
|
||||
}
|
||||
}
|
||||
|
||||
/// A single disallowed type, used by the `DISALLOWED_TYPES` lint.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum DisallowedType {
|
||||
Simple(String),
|
||||
WithReason { path: String, reason: Option<String> },
|
||||
pub fn reason(&self) -> Option<&str> {
|
||||
match self {
|
||||
Self::WithReason {
|
||||
reason: Some(reason), ..
|
||||
} => Some(reason),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Conf with parse errors
|
||||
|
@ -315,14 +315,18 @@ define_Conf! {
|
|||
///
|
||||
/// Whether to allow certain wildcard imports (prelude, super in tests).
|
||||
(warn_on_all_wildcard_imports: bool = false),
|
||||
/// Lint: DISALLOWED_MACROS.
|
||||
///
|
||||
/// The list of disallowed macros, written as fully qualified paths.
|
||||
(disallowed_macros: Vec<crate::utils::conf::DisallowedPath> = Vec::new()),
|
||||
/// Lint: DISALLOWED_METHODS.
|
||||
///
|
||||
/// The list of disallowed methods, written as fully qualified paths.
|
||||
(disallowed_methods: Vec<crate::utils::conf::DisallowedMethod> = Vec::new()),
|
||||
(disallowed_methods: Vec<crate::utils::conf::DisallowedPath> = Vec::new()),
|
||||
/// Lint: DISALLOWED_TYPES.
|
||||
///
|
||||
/// The list of disallowed types, written as fully qualified paths.
|
||||
(disallowed_types: Vec<crate::utils::conf::DisallowedType> = Vec::new()),
|
||||
(disallowed_types: Vec<crate::utils::conf::DisallowedPath> = Vec::new()),
|
||||
/// Lint: UNREADABLE_LITERAL.
|
||||
///
|
||||
/// Should the fraction of a decimal be linted to include separators.
|
||||
|
@ -362,7 +366,7 @@ define_Conf! {
|
|||
/// For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements.
|
||||
(max_suggested_slice_pattern_length: u64 = 3),
|
||||
/// Lint: AWAIT_HOLDING_INVALID_TYPE
|
||||
(await_holding_invalid_types: Vec<crate::utils::conf::DisallowedType> = Vec::new()),
|
||||
(await_holding_invalid_types: Vec<crate::utils::conf::DisallowedPath> = Vec::new()),
|
||||
/// Lint: LARGE_INCLUDE_FILE.
|
||||
///
|
||||
/// The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
|
||||
|
|
|
@ -15,7 +15,7 @@ use rustc_ast::visit::FnKind;
|
|||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def::{DefKind, Namespace, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::hir_id::CRATE_HIR_ID;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
|
@ -920,7 +920,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryDefPath {
|
|||
// Extract the path to the matched type
|
||||
if let Some(segments) = path_to_matched_type(cx, item_arg);
|
||||
let segments: Vec<&str> = segments.iter().map(|sym| &**sym).collect();
|
||||
if let Some(def_id) = def_path_res(cx, &segments[..]).opt_def_id();
|
||||
if let Some(def_id) = def_path_res(cx, &segments[..], None).opt_def_id();
|
||||
then {
|
||||
// def_path_res will match field names before anything else, but for this we want to match
|
||||
// inherent functions first.
|
||||
|
@ -952,7 +952,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryDefPath {
|
|||
Item::DiagnosticItem(*item_name),
|
||||
)
|
||||
} else if let Some(lang_item) = cx.tcx.lang_items().items().iter().position(|id| *id == Some(def_id)) {
|
||||
let lang_items = def_path_res(cx, &["rustc_hir", "lang_items", "LangItem"]).def_id();
|
||||
let lang_items = def_path_res(cx, &["rustc_hir", "lang_items", "LangItem"], Some(Namespace::TypeNS)).def_id();
|
||||
let item_name = cx.tcx.adt_def(lang_items).variants().iter().nth(lang_item).unwrap().name;
|
||||
(
|
||||
"use of a def path to a `LangItem`",
|
||||
|
@ -1115,7 +1115,7 @@ fn read_mir_alloc_def_path<'tcx>(cx: &LateContext<'tcx>, alloc: &'tcx Allocation
|
|||
// This is not a complete resolver for paths. It works on all the paths currently used in the paths
|
||||
// module. That's all it does and all it needs to do.
|
||||
pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool {
|
||||
if def_path_res(cx, path) != Res::Err {
|
||||
if def_path_res(cx, path, None) != Res::Err {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1206,7 +1206,7 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
|
|||
}
|
||||
|
||||
for &module in &[&paths::KW_MODULE, &paths::SYM_MODULE] {
|
||||
if let Some(def_id) = def_path_res(cx, module).opt_def_id() {
|
||||
if let Some(def_id) = def_path_res(cx, module, None).opt_def_id() {
|
||||
for item in cx.tcx.module_children(def_id).iter() {
|
||||
if_chain! {
|
||||
if let Res::Def(DefKind::Const, item_def_id) = item.res;
|
||||
|
|
|
@ -78,7 +78,7 @@ use rustc_ast::Attribute;
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::unhash::UnhashMap;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def::{DefKind, Namespace, Res};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
|
||||
use rustc_hir::hir_id::{HirIdMap, HirIdSet};
|
||||
use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
|
||||
|
@ -522,15 +522,49 @@ pub fn path_def_id<'tcx>(cx: &LateContext<'_>, maybe_path: &impl MaybePath<'tcx>
|
|||
path_res(cx, maybe_path).opt_def_id()
|
||||
}
|
||||
|
||||
/// Resolves a def path like `std::vec::Vec`.
|
||||
fn find_primitive<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator<Item = DefId> + 'tcx {
|
||||
let single = |ty| tcx.incoherent_impls(ty).iter().copied();
|
||||
let empty = || [].iter().copied();
|
||||
match name {
|
||||
"bool" => single(BoolSimplifiedType),
|
||||
"char" => single(CharSimplifiedType),
|
||||
"str" => single(StrSimplifiedType),
|
||||
"array" => single(ArraySimplifiedType),
|
||||
"slice" => single(SliceSimplifiedType),
|
||||
// FIXME: rustdoc documents these two using just `pointer`.
|
||||
//
|
||||
// Maybe this is something we should do here too.
|
||||
"const_ptr" => single(PtrSimplifiedType(Mutability::Not)),
|
||||
"mut_ptr" => single(PtrSimplifiedType(Mutability::Mut)),
|
||||
"isize" => single(IntSimplifiedType(IntTy::Isize)),
|
||||
"i8" => single(IntSimplifiedType(IntTy::I8)),
|
||||
"i16" => single(IntSimplifiedType(IntTy::I16)),
|
||||
"i32" => single(IntSimplifiedType(IntTy::I32)),
|
||||
"i64" => single(IntSimplifiedType(IntTy::I64)),
|
||||
"i128" => single(IntSimplifiedType(IntTy::I128)),
|
||||
"usize" => single(UintSimplifiedType(UintTy::Usize)),
|
||||
"u8" => single(UintSimplifiedType(UintTy::U8)),
|
||||
"u16" => single(UintSimplifiedType(UintTy::U16)),
|
||||
"u32" => single(UintSimplifiedType(UintTy::U32)),
|
||||
"u64" => single(UintSimplifiedType(UintTy::U64)),
|
||||
"u128" => single(UintSimplifiedType(UintTy::U128)),
|
||||
"f32" => single(FloatSimplifiedType(FloatTy::F32)),
|
||||
"f64" => single(FloatSimplifiedType(FloatTy::F64)),
|
||||
_ => empty(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolves a def path like `std::vec::Vec`. `namespace_hint` can be supplied to disambiguate
|
||||
/// between `std::vec` the module and `std::vec` the macro
|
||||
///
|
||||
/// This function is expensive and should be used sparingly.
|
||||
pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
||||
fn item_child_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: &str) -> Option<Res> {
|
||||
pub fn def_path_res(cx: &LateContext<'_>, path: &[&str], namespace_hint: Option<Namespace>) -> Res {
|
||||
fn item_child_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: &str, matches_ns: impl Fn(Res) -> bool) -> Option<Res> {
|
||||
match tcx.def_kind(def_id) {
|
||||
DefKind::Mod | DefKind::Enum | DefKind::Trait => tcx
|
||||
.module_children(def_id)
|
||||
.iter()
|
||||
.find(|item| item.ident.name.as_str() == name)
|
||||
.find(|item| item.ident.name.as_str() == name && matches_ns(item.res.expect_non_local()))
|
||||
.map(|child| child.res.expect_non_local()),
|
||||
DefKind::Impl => tcx
|
||||
.associated_item_def_ids(def_id)
|
||||
|
@ -548,37 +582,7 @@ pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
fn find_primitive<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator<Item = DefId> + 'tcx {
|
||||
let single = |ty| tcx.incoherent_impls(ty).iter().copied();
|
||||
let empty = || [].iter().copied();
|
||||
match name {
|
||||
"bool" => single(BoolSimplifiedType),
|
||||
"char" => single(CharSimplifiedType),
|
||||
"str" => single(StrSimplifiedType),
|
||||
"array" => single(ArraySimplifiedType),
|
||||
"slice" => single(SliceSimplifiedType),
|
||||
// FIXME: rustdoc documents these two using just `pointer`.
|
||||
//
|
||||
// Maybe this is something we should do here too.
|
||||
"const_ptr" => single(PtrSimplifiedType(Mutability::Not)),
|
||||
"mut_ptr" => single(PtrSimplifiedType(Mutability::Mut)),
|
||||
"isize" => single(IntSimplifiedType(IntTy::Isize)),
|
||||
"i8" => single(IntSimplifiedType(IntTy::I8)),
|
||||
"i16" => single(IntSimplifiedType(IntTy::I16)),
|
||||
"i32" => single(IntSimplifiedType(IntTy::I32)),
|
||||
"i64" => single(IntSimplifiedType(IntTy::I64)),
|
||||
"i128" => single(IntSimplifiedType(IntTy::I128)),
|
||||
"usize" => single(UintSimplifiedType(UintTy::Usize)),
|
||||
"u8" => single(UintSimplifiedType(UintTy::U8)),
|
||||
"u16" => single(UintSimplifiedType(UintTy::U16)),
|
||||
"u32" => single(UintSimplifiedType(UintTy::U32)),
|
||||
"u64" => single(UintSimplifiedType(UintTy::U64)),
|
||||
"u128" => single(UintSimplifiedType(UintTy::U128)),
|
||||
"f32" => single(FloatSimplifiedType(FloatTy::F32)),
|
||||
"f64" => single(FloatSimplifiedType(FloatTy::F64)),
|
||||
_ => empty(),
|
||||
}
|
||||
}
|
||||
|
||||
fn find_crate(tcx: TyCtxt<'_>, name: &str) -> Option<DefId> {
|
||||
tcx.crates(())
|
||||
.iter()
|
||||
|
@ -587,32 +591,45 @@ pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
|||
.map(CrateNum::as_def_id)
|
||||
}
|
||||
|
||||
let (base, first, path) = match *path {
|
||||
[base, first, ref path @ ..] => (base, first, path),
|
||||
let (base, path) = match *path {
|
||||
[primitive] => {
|
||||
return PrimTy::from_name(Symbol::intern(primitive)).map_or(Res::Err, Res::PrimTy);
|
||||
},
|
||||
[base, ref path @ ..] => (base, path),
|
||||
_ => return Res::Err,
|
||||
};
|
||||
let tcx = cx.tcx;
|
||||
let starts = find_primitive(tcx, base)
|
||||
.chain(find_crate(tcx, base))
|
||||
.filter_map(|id| item_child_by_name(tcx, id, first));
|
||||
.map(|id| Res::Def(tcx.def_kind(id), id));
|
||||
|
||||
for first in starts {
|
||||
let last = path
|
||||
.iter()
|
||||
.copied()
|
||||
.enumerate()
|
||||
// for each segment, find the child item
|
||||
.try_fold(first, |res, segment| {
|
||||
.try_fold(first, |res, (idx, segment)| {
|
||||
let matches_ns = |res: Res| {
|
||||
// If at the last segment in the path, respect the namespace hint
|
||||
if idx == path.len() - 1 {
|
||||
match namespace_hint {
|
||||
Some(ns) => res.matches_ns(ns),
|
||||
None => true,
|
||||
}
|
||||
} else {
|
||||
res.matches_ns(Namespace::TypeNS)
|
||||
}
|
||||
};
|
||||
|
||||
let def_id = res.def_id();
|
||||
if let Some(item) = item_child_by_name(tcx, def_id, segment) {
|
||||
if let Some(item) = item_child_by_name(tcx, def_id, segment, matches_ns) {
|
||||
Some(item)
|
||||
} else if matches!(res, Res::Def(DefKind::Enum | DefKind::Struct, _)) {
|
||||
// it is not a child item so check inherent impl items
|
||||
tcx.inherent_impls(def_id)
|
||||
.iter()
|
||||
.find_map(|&impl_def_id| item_child_by_name(tcx, impl_def_id, segment))
|
||||
.find_map(|&impl_def_id| item_child_by_name(tcx, impl_def_id, segment, matches_ns))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -628,8 +645,10 @@ pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
|||
|
||||
/// Convenience function to get the `DefId` of a trait by path.
|
||||
/// It could be a trait or trait alias.
|
||||
///
|
||||
/// This function is expensive and should be used sparingly.
|
||||
pub fn get_trait_def_id(cx: &LateContext<'_>, path: &[&str]) -> Option<DefId> {
|
||||
match def_path_res(cx, path) {
|
||||
match def_path_res(cx, path, Some(Namespace::TypeNS)) {
|
||||
Res::Def(DefKind::Trait | DefKind::TraitAlias, trait_id) => Some(trait_id),
|
||||
_ => None,
|
||||
}
|
||||
|
|
|
@ -106,6 +106,7 @@ docs! {
|
|||
"derive_hash_xor_eq",
|
||||
"derive_ord_xor_partial_ord",
|
||||
"derive_partial_eq_without_eq",
|
||||
"disallowed_macros",
|
||||
"disallowed_methods",
|
||||
"disallowed_names",
|
||||
"disallowed_script_idents",
|
||||
|
|
36
src/docs/disallowed_macros.txt
Normal file
36
src/docs/disallowed_macros.txt
Normal file
|
@ -0,0 +1,36 @@
|
|||
### What it does
|
||||
Denies the configured macros in clippy.toml
|
||||
|
||||
Note: Even though this lint is warn-by-default, it will only trigger if
|
||||
macros are defined in the clippy.toml file.
|
||||
|
||||
### Why is this bad?
|
||||
Some macros are undesirable in certain contexts, and it's beneficial to
|
||||
lint for them as needed.
|
||||
|
||||
### Example
|
||||
An example clippy.toml configuration:
|
||||
```
|
||||
disallowed-macros = [
|
||||
# Can use a string as the path of the disallowed macro.
|
||||
"std::print",
|
||||
# Can also use an inline table with a `path` key.
|
||||
{ path = "std::println" },
|
||||
# When using an inline table, can add a `reason` for why the macro
|
||||
# is disallowed.
|
||||
{ path = "serde::Serialize", reason = "no serializing" },
|
||||
]
|
||||
```
|
||||
```
|
||||
use serde::Serialize;
|
||||
|
||||
// Example code where clippy issues a warning
|
||||
println!("warns");
|
||||
|
||||
// The diagnostic will contain the message "no serializing"
|
||||
#[derive(Serialize)]
|
||||
struct Data {
|
||||
name: String,
|
||||
value: usize,
|
||||
}
|
||||
```
|
32
tests/ui-toml/disallowed_macros/auxiliary/macros.rs
Normal file
32
tests/ui-toml/disallowed_macros/auxiliary/macros.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
#[macro_export]
|
||||
macro_rules! expr {
|
||||
() => {
|
||||
1
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! stmt {
|
||||
() => {
|
||||
let _x = ();
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! ty {
|
||||
() => { &'static str };
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! pat {
|
||||
() => {
|
||||
_
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! item {
|
||||
() => {
|
||||
const ITEM: usize = 1;
|
||||
};
|
||||
}
|
11
tests/ui-toml/disallowed_macros/clippy.toml
Normal file
11
tests/ui-toml/disallowed_macros/clippy.toml
Normal file
|
@ -0,0 +1,11 @@
|
|||
disallowed-macros = [
|
||||
"std::println",
|
||||
"std::vec",
|
||||
{ path = "std::cfg" },
|
||||
{ path = "serde::Serialize", reason = "no serializing" },
|
||||
"macros::expr",
|
||||
"macros::stmt",
|
||||
"macros::ty",
|
||||
"macros::pat",
|
||||
"macros::item",
|
||||
]
|
39
tests/ui-toml/disallowed_macros/disallowed_macros.rs
Normal file
39
tests/ui-toml/disallowed_macros/disallowed_macros.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
// aux-build:macros.rs
|
||||
|
||||
#![allow(unused)]
|
||||
|
||||
extern crate macros;
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
fn main() {
|
||||
println!("one");
|
||||
println!("two");
|
||||
cfg!(unix);
|
||||
vec![1, 2, 3];
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Derive;
|
||||
|
||||
let _ = macros::expr!();
|
||||
macros::stmt!();
|
||||
let macros::pat!() = 1;
|
||||
let _: macros::ty!() = "";
|
||||
macros::item!();
|
||||
|
||||
eprintln!("allowed");
|
||||
}
|
||||
|
||||
struct S;
|
||||
|
||||
impl S {
|
||||
macros::item!();
|
||||
}
|
||||
|
||||
trait Y {
|
||||
macros::item!();
|
||||
}
|
||||
|
||||
impl Y for S {
|
||||
macros::item!();
|
||||
}
|
84
tests/ui-toml/disallowed_macros/disallowed_macros.stderr
Normal file
84
tests/ui-toml/disallowed_macros/disallowed_macros.stderr
Normal file
|
@ -0,0 +1,84 @@
|
|||
error: use of a disallowed macro `std::println`
|
||||
--> $DIR/disallowed_macros.rs:10:5
|
||||
|
|
||||
LL | println!("one");
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::disallowed-macros` implied by `-D warnings`
|
||||
|
||||
error: use of a disallowed macro `std::println`
|
||||
--> $DIR/disallowed_macros.rs:11:5
|
||||
|
|
||||
LL | println!("two");
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: use of a disallowed macro `std::cfg`
|
||||
--> $DIR/disallowed_macros.rs:12:5
|
||||
|
|
||||
LL | cfg!(unix);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: use of a disallowed macro `std::vec`
|
||||
--> $DIR/disallowed_macros.rs:13:5
|
||||
|
|
||||
LL | vec![1, 2, 3];
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: use of a disallowed macro `serde::Serialize`
|
||||
--> $DIR/disallowed_macros.rs:15:14
|
||||
|
|
||||
LL | #[derive(Serialize)]
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: no serializing (from clippy.toml)
|
||||
|
||||
error: use of a disallowed macro `macros::expr`
|
||||
--> $DIR/disallowed_macros.rs:18:13
|
||||
|
|
||||
LL | let _ = macros::expr!();
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: use of a disallowed macro `macros::stmt`
|
||||
--> $DIR/disallowed_macros.rs:19:5
|
||||
|
|
||||
LL | macros::stmt!();
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: use of a disallowed macro `macros::pat`
|
||||
--> $DIR/disallowed_macros.rs:20:9
|
||||
|
|
||||
LL | let macros::pat!() = 1;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: use of a disallowed macro `macros::ty`
|
||||
--> $DIR/disallowed_macros.rs:21:12
|
||||
|
|
||||
LL | let _: macros::ty!() = "";
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: use of a disallowed macro `macros::item`
|
||||
--> $DIR/disallowed_macros.rs:22:5
|
||||
|
|
||||
LL | macros::item!();
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: use of a disallowed macro `macros::item`
|
||||
--> $DIR/disallowed_macros.rs:30:5
|
||||
|
|
||||
LL | macros::item!();
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: use of a disallowed macro `macros::item`
|
||||
--> $DIR/disallowed_macros.rs:34:5
|
||||
|
|
||||
LL | macros::item!();
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: use of a disallowed macro `macros::item`
|
||||
--> $DIR/disallowed_macros.rs:38:5
|
||||
|
|
||||
LL | macros::item!();
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
|
|
@ -3,6 +3,7 @@ disallowed-methods = [
|
|||
"std::iter::Iterator::sum",
|
||||
"f32::clamp",
|
||||
"slice::sort_unstable",
|
||||
"futures::stream::select_all",
|
||||
# can give path and reason with an inline table
|
||||
{ path = "regex::Regex::is_match", reason = "no matching allowed" },
|
||||
# can use an inline table but omit reason
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#![warn(clippy::disallowed_methods)]
|
||||
|
||||
extern crate futures;
|
||||
extern crate regex;
|
||||
|
||||
use futures::stream::{empty, select_all};
|
||||
use regex::Regex;
|
||||
|
||||
fn main() {
|
||||
|
@ -20,4 +23,7 @@ fn main() {
|
|||
|
||||
let in_call = Box::new(f32::clamp);
|
||||
let in_method_call = ["^", "$"].into_iter().map(Regex::new);
|
||||
|
||||
// resolve ambiguity between `futures::stream::select_all` the module and the function
|
||||
let same_name_as_module = select_all(vec![empty::<()>()]);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: use of a disallowed method `regex::Regex::new`
|
||||
--> $DIR/conf_disallowed_methods.rs:7:14
|
||||
--> $DIR/conf_disallowed_methods.rs:10:14
|
||||
|
|
||||
LL | let re = Regex::new(r"ab.*c").unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -7,7 +7,7 @@ LL | let re = Regex::new(r"ab.*c").unwrap();
|
|||
= note: `-D clippy::disallowed-methods` implied by `-D warnings`
|
||||
|
||||
error: use of a disallowed method `regex::Regex::is_match`
|
||||
--> $DIR/conf_disallowed_methods.rs:8:5
|
||||
--> $DIR/conf_disallowed_methods.rs:11:5
|
||||
|
|
||||
LL | re.is_match("abc");
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
@ -15,40 +15,46 @@ LL | re.is_match("abc");
|
|||
= note: no matching allowed (from clippy.toml)
|
||||
|
||||
error: use of a disallowed method `std::iter::Iterator::sum`
|
||||
--> $DIR/conf_disallowed_methods.rs:11:5
|
||||
--> $DIR/conf_disallowed_methods.rs:14:5
|
||||
|
|
||||
LL | a.iter().sum::<i32>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: use of a disallowed method `slice::sort_unstable`
|
||||
--> $DIR/conf_disallowed_methods.rs:13:5
|
||||
--> $DIR/conf_disallowed_methods.rs:16:5
|
||||
|
|
||||
LL | a.sort_unstable();
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: use of a disallowed method `f32::clamp`
|
||||
--> $DIR/conf_disallowed_methods.rs:15:13
|
||||
--> $DIR/conf_disallowed_methods.rs:18:13
|
||||
|
|
||||
LL | let _ = 2.0f32.clamp(3.0f32, 4.0f32);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: use of a disallowed method `regex::Regex::new`
|
||||
--> $DIR/conf_disallowed_methods.rs:18:61
|
||||
--> $DIR/conf_disallowed_methods.rs:21:61
|
||||
|
|
||||
LL | let indirect: fn(&str) -> Result<Regex, regex::Error> = Regex::new;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: use of a disallowed method `f32::clamp`
|
||||
--> $DIR/conf_disallowed_methods.rs:21:28
|
||||
--> $DIR/conf_disallowed_methods.rs:24:28
|
||||
|
|
||||
LL | let in_call = Box::new(f32::clamp);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: use of a disallowed method `regex::Regex::new`
|
||||
--> $DIR/conf_disallowed_methods.rs:22:53
|
||||
--> $DIR/conf_disallowed_methods.rs:25:53
|
||||
|
|
||||
LL | let in_method_call = ["^", "$"].into_iter().map(Regex::new);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error: use of a disallowed method `futures::stream::select_all`
|
||||
--> $DIR/conf_disallowed_methods.rs:28:31
|
||||
|
|
||||
LL | let same_name_as_module = select_all(vec![empty::<()>()]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown fie
|
|||
cargo-ignore-publish
|
||||
cognitive-complexity-threshold
|
||||
cyclomatic-complexity-threshold
|
||||
disallowed-macros
|
||||
disallowed-methods
|
||||
disallowed-names
|
||||
disallowed-types
|
||||
|
|
Loading…
Reference in a new issue