Move redundant_allocation to its own module

This commit is contained in:
Yoshitomo Nakanishi 2021-02-11 17:41:14 +09:00
parent df307c0ce7
commit 128f1f5e2e
3 changed files with 112 additions and 88 deletions

View file

@ -1,6 +1,8 @@
#![allow(rustc::default_hash_types)]
mod box_vec;
mod redundant_allocation;
mod utils;
use std::borrow::Cow;
use std::cmp::Ordering;
@ -13,8 +15,8 @@ use rustc_hir as hir;
use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisitorMap, Visitor};
use rustc_hir::{
BinOpKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, FnSig, GenericArg, GenericBounds, GenericParamKind, HirId,
ImplItem, ImplItemKind, Item, ItemKind, LangItem, Lifetime, Lit, Local, MatchSource, MutTy, Mutability, Node,
QPath, Stmt, StmtKind, SyntheticTyParamKind, TraitFn, TraitItem, TraitItemKind, TyKind, UnOp,
ImplItem, ImplItemKind, Item, ItemKind, Lifetime, Lit, Local, MatchSource, MutTy, Mutability, Node, QPath, Stmt,
StmtKind, SyntheticTyParamKind, TraitFn, TraitItem, TraitItemKind, TyKind, UnOp,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::hir::map::Map;
@ -35,10 +37,10 @@ use crate::utils::paths;
use crate::utils::sugg::Sugg;
use crate::utils::{
clip, comparisons, differing_macro_contexts, get_qpath_generic_tys, higher, in_constant, indent_of, int_bits,
is_hir_ty_cfg_dependant, is_ty_param_diagnostic_item, is_ty_param_lang_item, is_type_diagnostic_item,
last_path_segment, match_def_path, match_path, meets_msrv, method_chain_args, multispan_sugg,
numeric_literal::NumericLiteral, reindent_multiline, sext, snippet, snippet_opt, snippet_with_applicability,
snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, unsext,
is_hir_ty_cfg_dependant, is_ty_param_diagnostic_item, is_type_diagnostic_item, last_path_segment, match_def_path,
match_path, meets_msrv, method_chain_args, multispan_sugg, numeric_literal::NumericLiteral, reindent_multiline,
sext, snippet, snippet_opt, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help,
span_lint_and_sugg, span_lint_and_then, unsext,
};
declare_clippy_lint! {
@ -301,23 +303,6 @@ fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static
}
}
fn match_borrows_parameter(_cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<Span> {
let last = last_path_segment(qpath);
if_chain! {
if let Some(ref params) = last.args;
if !params.parenthesized;
if let Some(ty) = params.args.iter().find_map(|arg| match arg {
GenericArg::Type(ty) => Some(ty),
_ => None,
});
if let TyKind::Rptr(..) = ty.kind;
then {
return Some(ty.span);
}
}
None
}
impl Types {
pub fn new(vec_box_size_threshold: u64) -> Self {
Self { vec_box_size_threshold }
@ -349,58 +334,8 @@ impl Types {
let res = cx.qpath_res(qpath, hir_id);
if let Some(def_id) = res.opt_def_id() {
box_vec::check(cx, hir_ty, qpath, def_id);
if Some(def_id) == cx.tcx.lang_items().owned_box() {
if let Some(span) = match_borrows_parameter(cx, qpath) {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg(
cx,
REDUNDANT_ALLOCATION,
hir_ty.span,
"usage of `Box<&T>`",
"try",
snippet_with_applicability(cx, span, "..", &mut applicability).to_string(),
applicability,
);
return; // don't recurse into the type
}
} else if cx.tcx.is_diagnostic_item(sym::Rc, def_id) {
if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Rc) {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg(
cx,
REDUNDANT_ALLOCATION,
hir_ty.span,
"usage of `Rc<Rc<T>>`",
"try",
snippet_with_applicability(cx, ty.span, "..", &mut applicability).to_string(),
applicability,
);
return; // don't recurse into the type
}
if let Some(ty) = is_ty_param_lang_item(cx, qpath, LangItem::OwnedBox) {
let qpath = match &ty.kind {
TyKind::Path(qpath) => qpath,
_ => return,
};
let inner_span = match get_qpath_generic_tys(qpath).next() {
Some(ty) => ty.span,
None => return,
};
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg(
cx,
REDUNDANT_ALLOCATION,
hir_ty.span,
"usage of `Rc<Box<T>>`",
"try",
format!(
"Rc<{}>",
snippet_with_applicability(cx, inner_span, "..", &mut applicability)
),
applicability,
);
return; // don't recurse into the type
}
redundant_allocation::check(cx, hir_ty, qpath, def_id);
if cx.tcx.is_diagnostic_item(sym::Rc, def_id) {
if let Some(alternate) = match_buffer_type(cx, qpath) {
span_lint_and_sugg(
cx,
@ -437,19 +372,6 @@ impl Types {
);
return; // don't recurse into the type
}
if let Some(span) = match_borrows_parameter(cx, qpath) {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg(
cx,
REDUNDANT_ALLOCATION,
hir_ty.span,
"usage of `Rc<&T>`",
"try",
snippet_with_applicability(cx, span, "..", &mut applicability).to_string(),
applicability,
);
return; // don't recurse into the type
}
} else if cx.tcx.is_diagnostic_item(sym::Arc, def_id) {
if let Some(alternate) = match_buffer_type(cx, qpath) {
span_lint_and_sugg(

View file

@ -0,0 +1,78 @@
use rustc_errors::Applicability;
use rustc_hir::{self as hir, def_id::DefId, LangItem, QPath, TyKind};
use rustc_lint::LateContext;
use rustc_span::symbol::sym;
use crate::utils::{
get_qpath_generic_tys, is_ty_param_diagnostic_item, is_ty_param_lang_item, snippet_with_applicability,
span_lint_and_sugg,
};
use super::{utils, REDUNDANT_ALLOCATION};
pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) {
if Some(def_id) == cx.tcx.lang_items().owned_box() {
if let Some(span) = utils::match_borrows_parameter(cx, qpath) {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg(
cx,
REDUNDANT_ALLOCATION,
hir_ty.span,
"usage of `Box<&T>`",
"try",
snippet_with_applicability(cx, span, "..", &mut applicability).to_string(),
applicability,
);
return;
}
}
if cx.tcx.is_diagnostic_item(sym::Rc, def_id) {
if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Rc) {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg(
cx,
REDUNDANT_ALLOCATION,
hir_ty.span,
"usage of `Rc<Rc<T>>`",
"try",
snippet_with_applicability(cx, ty.span, "..", &mut applicability).to_string(),
applicability,
);
} else if let Some(ty) = is_ty_param_lang_item(cx, qpath, LangItem::OwnedBox) {
let qpath = match &ty.kind {
TyKind::Path(qpath) => qpath,
_ => return,
};
let inner_span = match get_qpath_generic_tys(qpath).next() {
Some(ty) => ty.span,
None => return,
};
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg(
cx,
REDUNDANT_ALLOCATION,
hir_ty.span,
"usage of `Rc<Box<T>>`",
"try",
format!(
"Rc<{}>",
snippet_with_applicability(cx, inner_span, "..", &mut applicability)
),
applicability,
);
} else if let Some(span) = utils::match_borrows_parameter(cx, qpath) {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg(
cx,
REDUNDANT_ALLOCATION,
hir_ty.span,
"usage of `Rc<&T>`",
"try",
snippet_with_applicability(cx, span, "..", &mut applicability).to_string(),
applicability,
);
return; // don't recurse into the type
}
}
}

View file

@ -0,0 +1,24 @@
use rustc_hir::{GenericArg, QPath, TyKind};
use rustc_lint::LateContext;
use rustc_span::source_map::Span;
use crate::utils::last_path_segment;
use if_chain::if_chain;
pub(super) fn match_borrows_parameter(_cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<Span> {
let last = last_path_segment(qpath);
if_chain! {
if let Some(ref params) = last.args;
if !params.parenthesized;
if let Some(ty) = params.args.iter().find_map(|arg| match arg {
GenericArg::Type(ty) => Some(ty),
_ => None,
});
if let TyKind::Rptr(..) = ty.kind;
then {
return Some(ty.span);
}
}
None
}