Skip to content

Commit ae9c2a4

Browse files
committed
WIP: is_used_anywhere_else
1 parent d98d1ff commit ae9c2a4

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

clippy_lints/src/needless_path_new.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
77
use rustc_hir::def_id::DefId;
88
use rustc_hir::{Expr, ExprKind, QPath};
99
use rustc_lint::{LateContext, LateLintPass};
10-
use rustc_middle::ty::{List, Ty, TyCtxt};
10+
use rustc_middle::ty::{self, List, ParamTy, Ty, TyCtxt};
1111
use rustc_session::impl_lint_pass;
1212
use rustc_span::sym;
1313
use std::iter;
@@ -99,6 +99,21 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPathNew<'tcx> {
9999

100100
let implements_asref_path = |arg| implements_trait(cx, arg, asref_def_id, &[path_ty.into()]);
101101

102+
let is_used_anywhere_else = |param_ty: &ParamTy, other_sig_tys: &[Ty<'_>]| {
103+
other_sig_tys.iter().any(|sig_ty| {
104+
sig_ty.walk().any(|generic_arg| {
105+
if let Some(ty) = generic_arg.as_type()
106+
&& let ty::Param(pt) = ty.kind()
107+
&& pt == param_ty
108+
{
109+
true
110+
} else {
111+
false
112+
}
113+
})
114+
})
115+
};
116+
102117
// as far as I understand, `ExprKind::MethodCall` doesn't include the receiver in `args`,
103118
// but does in `sig.inputs()` -- so we iterate over both in `rev`erse in order to line
104119
// them up starting from the _end_
@@ -110,7 +125,8 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPathNew<'tcx> {
110125
// we want `argument` to be `Path::new(x)`
111126
if let ExprKind::Call(path_new, [x]) = arg.kind
112127
&& is_path_new(path_new)
113-
&& implements_asref_path(cx.typeck_results().expr_ty(x))
128+
&& let ty::Param(arg_param_ty) = arg_ty.kind()
129+
&& !is_used_anywhere_else(arg_param_ty, sig.inputs())
114130
&& implements_asref_path(*arg_ty)
115131
{
116132
span_lint_and_sugg(

0 commit comments

Comments
 (0)