Skip to content

Commit e2c30f0

Browse files
committed
Ignore references to type aliases in ptr_arg
Works using the fact that the hir path will point to a TyAlias, rather than being resolved to the underlying type
1 parent 444ef3e commit e2c30f0

File tree

2 files changed

+36
-21
lines changed

2 files changed

+36
-21
lines changed

clippy_lints/src/ptr.rs

+32-21
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
44
use clippy_utils::ptr::get_spans;
55
use clippy_utils::source::snippet_opt;
6-
use clippy_utils::ty::{is_type_diagnostic_item, match_type, walk_ptrs_hir_ty};
6+
use clippy_utils::ty::walk_ptrs_hir_ty;
77
use clippy_utils::{expr_path_res, is_lint_allowed, match_any_diagnostic_items, paths};
88
use if_chain::if_chain;
99
use rustc_errors::Applicability;
10+
use rustc_hir::def::Res;
1011
use rustc_hir::{
11-
BinOpKind, BodyId, Expr, ExprKind, FnDecl, FnRetTy, GenericArg, HirId, Impl, ImplItem, ImplItemKind, Item,
12-
ItemKind, Lifetime, MutTy, Mutability, Node, PathSegment, QPath, TraitFn, TraitItem, TraitItemKind, Ty, TyKind,
12+
BinOpKind, BodyId, Expr, ExprKind, FnDecl, FnRetTy, GenericArg, Impl, ImplItem, ImplItemKind, Item, ItemKind,
13+
Lifetime, MutTy, Mutability, Node, PathSegment, QPath, TraitFn, TraitItem, TraitItemKind, Ty, TyKind,
1314
};
1415
use rustc_lint::{LateContext, LateLintPass};
15-
use rustc_middle::ty;
1616
use rustc_session::{declare_lint_pass, declare_tool_lint};
1717
use rustc_span::source_map::Span;
1818
use rustc_span::symbol::Symbol;
@@ -153,7 +153,7 @@ declare_lint_pass!(Ptr => [PTR_ARG, CMP_NULL, MUT_FROM_REF, INVALID_NULL_PTR_USA
153153
impl<'tcx> LateLintPass<'tcx> for Ptr {
154154
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
155155
if let ItemKind::Fn(ref sig, _, body_id) = item.kind {
156-
check_fn(cx, sig.decl, item.hir_id(), Some(body_id));
156+
check_fn(cx, sig.decl, Some(body_id));
157157
}
158158
}
159159

@@ -165,7 +165,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
165165
return; // ignore trait impls
166166
}
167167
}
168-
check_fn(cx, sig.decl, item.hir_id(), Some(body_id));
168+
check_fn(cx, sig.decl, Some(body_id));
169169
}
170170
}
171171

@@ -176,7 +176,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
176176
} else {
177177
None
178178
};
179-
check_fn(cx, sig.decl, item.hir_id(), body_id);
179+
check_fn(cx, sig.decl, body_id);
180180
}
181181
}
182182

@@ -244,22 +244,31 @@ fn check_invalid_ptr_usage<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
244244
}
245245

246246
#[allow(clippy::too_many_lines)]
247-
fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id: Option<BodyId>) {
248-
let fn_def_id = cx.tcx.hir().local_def_id(fn_id);
249-
let sig = cx.tcx.fn_sig(fn_def_id);
250-
let fn_ty = sig.skip_binder();
247+
fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, opt_body_id: Option<BodyId>) {
251248
let body = opt_body_id.map(|id| cx.tcx.hir().body(id));
252249

253-
for (idx, (arg, ty)) in decl.inputs.iter().zip(fn_ty.inputs()).enumerate() {
250+
for (idx, arg) in decl.inputs.iter().enumerate() {
254251
// Honor the allow attribute on parameters. See issue 5644.
255252
if let Some(body) = &body {
256253
if is_lint_allowed(cx, PTR_ARG, body.params[idx].hir_id) {
257254
continue;
258255
}
259256
}
260257

261-
if let ty::Ref(_, ty, Mutability::Not) = ty.kind() {
262-
if is_type_diagnostic_item(cx, ty, sym::Vec) {
258+
let (item_name, path) = if_chain! {
259+
if let TyKind::Rptr(_, MutTy { ty, mutbl: Mutability::Not }) = arg.kind;
260+
if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind;
261+
if let Res::Def(_, did) = path.res;
262+
if let Some(item_name) = cx.tcx.get_diagnostic_name(did);
263+
then {
264+
(item_name, path)
265+
} else {
266+
continue
267+
}
268+
};
269+
270+
match item_name {
271+
sym::Vec => {
263272
if let Some(spans) = get_spans(cx, opt_body_id, idx, &[("clone", ".to_owned()")]) {
264273
span_lint_and_then(
265274
cx,
@@ -289,7 +298,8 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id:
289298
},
290299
);
291300
}
292-
} else if is_type_diagnostic_item(cx, ty, sym::String) {
301+
},
302+
sym::String => {
293303
if let Some(spans) = get_spans(cx, opt_body_id, idx, &[("clone", ".to_string()"), ("as_str", "")]) {
294304
span_lint_and_then(
295305
cx,
@@ -311,7 +321,8 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id:
311321
},
312322
);
313323
}
314-
} else if is_type_diagnostic_item(cx, ty, sym::PathBuf) {
324+
},
325+
sym::PathBuf => {
315326
if let Some(spans) = get_spans(cx, opt_body_id, idx, &[("clone", ".to_path_buf()"), ("as_path", "")]) {
316327
span_lint_and_then(
317328
cx,
@@ -338,11 +349,10 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id:
338349
},
339350
);
340351
}
341-
} else if match_type(cx, ty, &paths::COW) {
352+
},
353+
sym::Cow => {
342354
if_chain! {
343-
if let TyKind::Rptr(_, MutTy { ty, ..} ) = arg.kind;
344-
if let TyKind::Path(QPath::Resolved(None, pp)) = ty.kind;
345-
if let [ref bx] = *pp.segments;
355+
if let [ref bx] = *path.segments;
346356
if let Some(params) = bx.args;
347357
if !params.parenthesized;
348358
if let Some(inner) = params.args.iter().find_map(|arg| match arg {
@@ -363,7 +373,8 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id:
363373
);
364374
}
365375
}
366-
}
376+
},
377+
_ => {},
367378
}
368379
}
369380

tests/ui/ptr_arg.rs

+4
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,7 @@ mod issue6509 {
160160
let _ = str.clone().clone();
161161
}
162162
}
163+
164+
// No error for types behind an alias (#7699)
165+
type A = Vec<u8>;
166+
fn aliased(a: &A) {}

0 commit comments

Comments
 (0)